Extract queue item holder to new class

First step to use a single item holder in the future
This commit is contained in:
ByteHamster 2020-02-04 14:53:49 +01:00
parent 7e2fd0b1d7
commit cae04b5b13
5 changed files with 272 additions and 301 deletions

View File

@ -1,56 +1,33 @@
package de.danoeh.antennapod.adapter; package de.danoeh.antennapod.adapter;
import android.os.Build;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.core.view.MotionEventCompat;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.ItemTouchHelper;
import android.text.Layout;
import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.view.ContextMenu; import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.MenuInflater; import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.FrameLayout; import androidx.annotation.NonNull;
import android.widget.ImageButton; import androidx.annotation.Nullable;
import android.widget.ImageView; import androidx.core.view.MotionEventCompat;
import android.widget.ProgressBar; import androidx.recyclerview.widget.ItemTouchHelper;
import android.widget.TextView; import androidx.recyclerview.widget.RecyclerView;
import de.danoeh.antennapod.R;
import com.joanzapata.iconify.Iconify; import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.event.PlaybackPositionEvent; import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.fragment.ItemPagerFragment; import de.danoeh.antennapod.fragment.ItemPagerFragment;
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
import de.danoeh.antennapod.view.EpisodeItemViewHolder;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.adapter.actionbutton.ItemActionButton;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DownloadRequester;
import de.danoeh.antennapod.core.util.Converter;
import de.danoeh.antennapod.core.util.DateUtils;
import de.danoeh.antennapod.core.feed.util.ImageResourceUtils;
import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.NetworkUtils;
import de.danoeh.antennapod.core.util.ThemeUtils;
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
/** /**
* List adapter for the queue. * List adapter for the queue.
*/ */
public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdapter.ViewHolder> { public class QueueRecyclerAdapter extends RecyclerView.Adapter<EpisodeItemViewHolder> implements View.OnCreateContextMenuListener {
private static final String TAG = "QueueRecyclerAdapter";
private static final String TAG = QueueRecyclerAdapter.class.getSimpleName();
private final WeakReference<MainActivity> mainActivity; private final WeakReference<MainActivity> mainActivity;
private final ItemAccess itemAccess; private final ItemAccess itemAccess;
@ -60,9 +37,6 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap
private FeedItem selectedItem; private FeedItem selectedItem;
private final int playingBackGroundColor;
private final int normalBackGroundColor;
public QueueRecyclerAdapter(MainActivity mainActivity, public QueueRecyclerAdapter(MainActivity mainActivity,
ItemAccess itemAccess, ItemAccess itemAccess,
ItemTouchHelper itemTouchHelper) { ItemTouchHelper itemTouchHelper) {
@ -71,9 +45,6 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap
this.itemAccess = itemAccess; this.itemAccess = itemAccess;
this.itemTouchHelper = itemTouchHelper; this.itemTouchHelper = itemTouchHelper;
locked = UserPreferences.isQueueLocked(); locked = UserPreferences.isQueueLocked();
playingBackGroundColor = ThemeUtils.getColorFromAttr(mainActivity, R.attr.currently_playing_background);
normalBackGroundColor = ContextCompat.getColor(mainActivity, android.R.color.transparent);
} }
public void setLocked(boolean locked) { public void setLocked(boolean locked) {
@ -81,20 +52,38 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap
notifyDataSetChanged(); notifyDataSetChanged();
} }
@NonNull
@Override @Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { public EpisodeItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.queue_listitem, parent, false); EpisodeItemViewHolder viewHolder = new EpisodeItemViewHolder(mainActivity.get());
return new ViewHolder(view); viewHolder.dragHandle.setOnTouchListener((v1, event) -> {
if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) {
Log.d(TAG, "startDrag()");
itemTouchHelper.startDrag(viewHolder);
}
return false;
});
return viewHolder;
} }
@Override @Override
public void onBindViewHolder(ViewHolder holder, int pos) { public void onBindViewHolder(EpisodeItemViewHolder holder, int pos) {
FeedItem item = itemAccess.getItem(pos); FeedItem item = itemAccess.getItem(pos);
holder.bind(item); holder.bind(item);
holder.dragHandle.setVisibility(locked ? View.GONE : View.VISIBLE);
holder.itemView.setOnLongClickListener(v -> { holder.itemView.setOnLongClickListener(v -> {
selectedItem = item; selectedItem = item;
return false; return false;
}); });
holder.itemView.setOnClickListener(v -> {
MainActivity activity = mainActivity.get();
if (activity != null) {
long[] ids = itemAccess.getQueueIds().toArray();
int position = ArrayUtils.indexOf(ids, item.getId());
activity.loadChildFragment(ItemPagerFragment.newInstance(ids, position));
}
});
holder.itemView.setOnCreateContextMenuListener(this);
} }
@Nullable @Nullable
@ -112,211 +101,30 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap
return itemAccess.getCount(); return itemAccess.getCount();
} }
public class ViewHolder extends RecyclerView.ViewHolder @Override
implements View.OnClickListener, public void onCreateContextMenu(final ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
View.OnCreateContextMenuListener, MenuInflater inflater = mainActivity.get().getMenuInflater();
ItemTouchHelperViewHolder { inflater.inflate(R.menu.queue_context, menu); // queue-specific menu items
inflater.inflate(R.menu.feeditemlist_context, menu); // generic menu items for item feeds
private final FrameLayout container; menu.setHeaderTitle(selectedItem.getTitle());
private final ImageView dragHandle; FeedItemMenuHandler.onPrepareMenu(menu, selectedItem, R.id.skip_episode_item);
private final TextView placeholder; // Queue-specific menu preparation
private final ImageView cover; final boolean keepSorted = UserPreferences.isQueueKeepSorted();
private final TextView title; final LongList queueAccess = itemAccess.getQueueIds();
private final TextView pubDate; if (queueAccess.size() == 0 || queueAccess.get(0) == selectedItem.getId() || keepSorted) {
private final TextView progressLeft; menu.findItem(R.id.move_to_top_item).setVisible(false);
private final TextView progressRight;
private final ProgressBar progressBar;
private final ImageButton butSecondary;
private FeedItem item;
public ViewHolder(View v) {
super(v);
container = v.findViewById(R.id.container);
dragHandle = v.findViewById(R.id.drag_handle);
placeholder = v.findViewById(R.id.txtvPlaceholder);
cover = v.findViewById(R.id.imgvCover);
title = v.findViewById(R.id.txtvTitle);
if(Build.VERSION.SDK_INT >= 23) {
title.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL);
}
pubDate = v.findViewById(R.id.txtvPubDate);
progressLeft = v.findViewById(R.id.txtvProgressLeft);
progressRight = v.findViewById(R.id.txtvProgressRight);
butSecondary = v.findViewById(R.id.butSecondaryAction);
progressBar = v.findViewById(R.id.progressBar);
v.setTag(this);
v.setOnClickListener(this);
v.setOnCreateContextMenuListener(this);
dragHandle.setOnTouchListener((v1, event) -> {
if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) {
Log.d(TAG, "startDrag()");
itemTouchHelper.startDrag(ViewHolder.this);
}
return false;
});
} }
if (queueAccess.size() == 0 || queueAccess.get(queueAccess.size() - 1) == selectedItem.getId() || keepSorted) {
@Override menu.findItem(R.id.move_to_bottom_item).setVisible(false);
public void onClick(View v) {
MainActivity activity = mainActivity.get();
if (activity != null) {
long[] ids = itemAccess.getQueueIds().toArray();
int position = ArrayUtils.indexOf(ids, item.getId());
activity.loadChildFragment(ItemPagerFragment.newInstance(ids, position));
}
}
@Override
public void onCreateContextMenu(final ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
FeedItem item = itemAccess.getItem(getAdapterPosition());
MenuInflater inflater = mainActivity.get().getMenuInflater();
inflater.inflate(R.menu.queue_context, menu); // queue-specific menu items
inflater.inflate(R.menu.feeditemlist_context, menu); // generic menu items for item feeds
if (item != null) {
menu.setHeaderTitle(item.getTitle());
}
FeedItemMenuHandler.onPrepareMenu(menu, item,
R.id.skip_episode_item); // Skip Episode is not useful in Queue, so hide it.
// Queue-specific menu preparation
final boolean keepSorted = UserPreferences.isQueueKeepSorted();
final LongList queueAccess = itemAccess.getQueueIds();
if (queueAccess.size() == 0 || queueAccess.get(0) == item.getId() || keepSorted) {
menu.findItem(R.id.move_to_top_item).setVisible(false);
}
if (queueAccess.size() == 0 || queueAccess.get(queueAccess.size()-1) == item.getId() || keepSorted) {
menu.findItem(R.id.move_to_bottom_item).setVisible(false);
}
}
@Override
public void onItemSelected() {
itemView.setAlpha(0.5f);
}
@Override
public void onItemClear() {
itemView.setAlpha(1.0f);
}
public void bind(FeedItem item) {
this.item = item;
if(locked) {
dragHandle.setVisibility(View.GONE);
} else {
dragHandle.setVisibility(View.VISIBLE);
}
placeholder.setText(item.getFeed().getTitle());
title.setText(item.getTitle());
FeedMedia media = item.getMedia();
title.setText(item.getTitle());
String pubDateStr = DateUtils.formatAbbrev(mainActivity.get(), item.getPubDate());
int index = 0;
if(countMatches(pubDateStr, ' ') == 1 || countMatches(pubDateStr, ' ') == 2) {
index = pubDateStr.lastIndexOf(' ');
} else if(countMatches(pubDateStr, '.') == 2) {
index = pubDateStr.lastIndexOf('.');
} else if(countMatches(pubDateStr, '-') == 2) {
index = pubDateStr.lastIndexOf('-');
} else if(countMatches(pubDateStr, '/') == 2) {
index = pubDateStr.lastIndexOf('/');
}
if(index > 0) {
pubDateStr = pubDateStr.substring(0, index+1).trim() + "\n" + pubDateStr.substring(index+1);
}
pubDate.setText(pubDateStr);
if (media != null) {
final boolean isDownloadingMedia = DownloadRequester.getInstance().isDownloadingFile(media);
FeedItem.State state = item.getState();
if (isDownloadingMedia) {
progressLeft.setText(Converter.byteToString(itemAccess.getItemDownloadedBytes(item)));
if(itemAccess.getItemDownloadSize(item) > 0) {
progressRight.setText(Converter.byteToString(itemAccess.getItemDownloadSize(item)));
} else {
progressRight.setText(Converter.byteToString(media.getSize()));
}
progressBar.setProgress(itemAccess.getItemDownloadProgressPercent(item));
progressBar.setVisibility(View.VISIBLE);
} else if (state == FeedItem.State.PLAYING
|| state == FeedItem.State.IN_PROGRESS) {
if (media.getDuration() > 0) {
int progress = (int) (100.0 * media.getPosition() / media.getDuration());
progressBar.setProgress(progress);
progressBar.setVisibility(View.VISIBLE);
progressLeft.setText(Converter
.getDurationStringLong(media.getPosition()));
progressRight.setText(Converter.getDurationStringLong(media.getDuration()));
}
} else {
if(media.getSize() > 0) {
progressLeft.setText(Converter.byteToString(media.getSize()));
} else if(NetworkUtils.isEpisodeHeadDownloadAllowed() && !media.checkedOnSizeButUnknown()) {
progressLeft.setText("{fa-spinner}");
Iconify.addIcons(progressLeft);
NetworkUtils.getFeedMediaSizeObservable(media)
.subscribe(
size -> {
if (size > 0) {
progressLeft.setText(Converter.byteToString(size));
} else {
progressLeft.setText("");
}
}, error -> {
progressLeft.setText("");
Log.e(TAG, Log.getStackTraceString(error));
});
} else {
progressLeft.setText("");
}
progressRight.setText(Converter.getDurationStringLong(media.getDuration()));
progressBar.setVisibility(View.INVISIBLE);
}
if(media.isCurrentlyPlaying()) {
container.setBackgroundColor(playingBackGroundColor);
} else {
container.setBackgroundColor(normalBackGroundColor);
}
}
ItemActionButton actionButton = ItemActionButton.forItem(item, true);
actionButton.configure(butSecondary, mainActivity.get());
butSecondary.setFocusable(false);
butSecondary.setTag(item);
new CoverLoader(mainActivity.get())
.withUri(ImageResourceUtils.getImageLocation(item))
.withFallbackUri(item.getFeed().getImageLocation())
.withPlaceholderView(placeholder)
.withCoverView(cover)
.load();
}
public boolean isCurrentlyPlayingItem() {
return item.getMedia() != null && item.getMedia().isCurrentlyPlaying();
}
public void notifyPlaybackPositionUpdated(PlaybackPositionEvent event) {
progressBar.setProgress((int) (100.0 * event.getPosition() / event.getDuration()));
progressLeft.setText(Converter.getDurationStringLong(event.getPosition()));
progressRight.setText(Converter.getDurationStringLong(event.getDuration()));
} }
} }
public interface ItemAccess { public interface ItemAccess {
FeedItem getItem(int position); FeedItem getItem(int position);
int getCount(); int getCount();
long getItemDownloadedBytes(FeedItem item);
long getItemDownloadSize(FeedItem item);
int getItemDownloadProgressPercent(FeedItem item);
LongList getQueueIds(); LongList getQueueIds();
} }
@ -341,18 +149,4 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap
*/ */
void onItemClear(); void onItemClear();
} }
// Oh Xiaomi, I hate you so much. How did you manage to fuck this up?
private static int countMatches(final CharSequence str, final char ch) {
if (TextUtils.isEmpty(str)) {
return 0;
}
int count = 0;
for (int i = 0; i < str.length(); i++) {
if (ch == str.charAt(i)) {
count++;
}
}
return count;
}
} }

View File

@ -27,6 +27,7 @@ import androidx.recyclerview.widget.SimpleItemAnimator;
import com.google.android.material.snackbar.Snackbar; import com.google.android.material.snackbar.Snackbar;
import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration; import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration;
import de.danoeh.antennapod.view.EpisodeItemViewHolder;
import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode; import org.greenrobot.eventbus.ThreadMode;
@ -84,7 +85,6 @@ public class QueueFragment extends Fragment {
private ProgressBar progLoading; private ProgressBar progLoading;
private List<FeedItem> queue; private List<FeedItem> queue;
private List<Downloader> downloaderList;
private boolean isUpdatingFeeds = false; private boolean isUpdatingFeeds = false;
@ -196,7 +196,6 @@ public class QueueFragment extends Fragment {
public void onEventMainThread(DownloadEvent event) { public void onEventMainThread(DownloadEvent event) {
Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]"); Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
DownloaderUpdate update = event.update; DownloaderUpdate update = event.update;
downloaderList = update.downloaders;
if (event.hasChangedFeedUpdateStatus(isUpdatingFeeds)) { if (event.hasChangedFeedUpdateStatus(isUpdatingFeeds)) {
getActivity().invalidateOptionsMenu(); getActivity().invalidateOptionsMenu();
} }
@ -214,7 +213,7 @@ public class QueueFragment extends Fragment {
public void onEventMainThread(PlaybackPositionEvent event) { public void onEventMainThread(PlaybackPositionEvent event) {
if (recyclerAdapter != null) { if (recyclerAdapter != null) {
for (int i = 0; i < recyclerAdapter.getItemCount(); i++) { for (int i = 0; i < recyclerAdapter.getItemCount(); i++) {
QueueRecyclerAdapter.ViewHolder holder = (QueueRecyclerAdapter.ViewHolder) EpisodeItemViewHolder holder = (EpisodeItemViewHolder)
recyclerView.findViewHolderForAdapterPosition(i); recyclerView.findViewHolderForAdapterPosition(i);
if (holder != null && holder.isCurrentlyPlayingItem()) { if (holder != null && holder.isCurrentlyPlayingItem()) {
holder.notifyPlaybackPositionUpdated(event); holder.notifyPlaybackPositionUpdated(event);
@ -688,46 +687,6 @@ public class QueueFragment extends Fragment {
return null; return null;
} }
@Override
public long getItemDownloadedBytes(FeedItem item) {
if (downloaderList != null) {
for (Downloader downloader : downloaderList) {
if (downloader.getDownloadRequest().getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA
&& downloader.getDownloadRequest().getFeedfileId() == item.getMedia().getId()) {
Log.d(TAG, "downloaded bytes: " + downloader.getDownloadRequest().getSoFar());
return downloader.getDownloadRequest().getSoFar();
}
}
}
return 0;
}
@Override
public long getItemDownloadSize(FeedItem item) {
if (downloaderList != null) {
for (Downloader downloader : downloaderList) {
if (downloader.getDownloadRequest().getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA
&& downloader.getDownloadRequest().getFeedfileId() == item.getMedia().getId()) {
Log.d(TAG, "downloaded size: " + downloader.getDownloadRequest().getSize());
return downloader.getDownloadRequest().getSize();
}
}
}
return 0;
}
@Override
public int getItemDownloadProgressPercent(FeedItem item) {
if (downloaderList != null) {
for (Downloader downloader : downloaderList) {
if (downloader.getDownloadRequest().getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA
&& downloader.getDownloadRequest().getFeedfileId() == item.getMedia().getId()) {
return downloader.getDownloadRequest().getProgressPercent();
}
}
}
return 0;
}
@Override @Override
public LongList getQueueIds() { public LongList getQueueIds() {
return queue != null ? LongList.of(FeedItemUtil.getIds(queue)) : new LongList(0); return queue != null ? LongList.of(FeedItemUtil.getIds(queue)) : new LongList(0);

View File

@ -0,0 +1,196 @@
package de.danoeh.antennapod.view;
import android.graphics.Color;
import android.os.Build;
import android.text.Layout;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import com.joanzapata.iconify.Iconify;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.adapter.CoverLoader;
import de.danoeh.antennapod.adapter.QueueRecyclerAdapter;
import de.danoeh.antennapod.adapter.actionbutton.ItemActionButton;
import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.feed.util.ImageResourceUtils;
import de.danoeh.antennapod.core.service.download.DownloadRequest;
import de.danoeh.antennapod.core.storage.DownloadRequester;
import de.danoeh.antennapod.core.util.Converter;
import de.danoeh.antennapod.core.util.DateUtils;
import de.danoeh.antennapod.core.util.NetworkUtils;
import de.danoeh.antennapod.core.util.ThemeUtils;
/**
* Holds the view which shows FeedItems.
*/
public class EpisodeItemViewHolder extends RecyclerView.ViewHolder
implements QueueRecyclerAdapter.ItemTouchHelperViewHolder {
private static final String TAG = "EpisodeItemViewHolder";
private final FrameLayout container;
public final ImageView dragHandle;
private final TextView placeholder;
private final ImageView cover;
private final TextView title;
private final TextView pubDate;
private final TextView progressLeft;
private final TextView progressRight;
private final ProgressBar progressBar;
private final ImageButton butSecondary;
private final MainActivity activity;
private FeedItem item;
public EpisodeItemViewHolder(MainActivity activity) {
super(View.inflate(activity, R.layout.queue_listitem, null));
this.activity = activity;
container = itemView.findViewById(R.id.container);
dragHandle = itemView.findViewById(R.id.drag_handle);
placeholder = itemView.findViewById(R.id.txtvPlaceholder);
cover = itemView.findViewById(R.id.imgvCover);
title = itemView.findViewById(R.id.txtvTitle);
if (Build.VERSION.SDK_INT >= 23) {
title.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL);
}
pubDate = itemView.findViewById(R.id.txtvPubDate);
progressLeft = itemView.findViewById(R.id.txtvProgressLeft);
progressRight = itemView.findViewById(R.id.txtvProgressRight);
butSecondary = itemView.findViewById(R.id.butSecondaryAction);
progressBar = itemView.findViewById(R.id.progressBar);
itemView.setTag(this);
}
@Override
public void onItemSelected() {
itemView.setAlpha(0.5f);
}
@Override
public void onItemClear() {
itemView.setAlpha(1.0f);
}
public void bind(FeedItem item) {
this.item = item;
placeholder.setText(item.getFeed().getTitle());
title.setText(item.getTitle());
title.setText(item.getTitle());
pubDate.setText(formatPubDate());
FeedMedia media = item.getMedia();
if (media != null) {
final DownloadRequest downloadRequest = DownloadRequester.getInstance().getRequestFor(media);
FeedItem.State state = item.getState();
if (downloadRequest != null) {
progressLeft.setText(Converter.byteToString(downloadRequest.getSoFar()));
if (downloadRequest.getSize() > 0) {
progressRight.setText(Converter.byteToString(downloadRequest.getSize()));
} else {
progressRight.setText(Converter.byteToString(media.getSize()));
}
progressBar.setProgress(downloadRequest.getProgressPercent());
progressBar.setVisibility(View.VISIBLE);
} else if (state == FeedItem.State.PLAYING || state == FeedItem.State.IN_PROGRESS) {
if (media.getDuration() > 0) {
int progress = (int) (100.0 * media.getPosition() / media.getDuration());
progressBar.setProgress(progress);
progressBar.setVisibility(View.VISIBLE);
progressLeft.setText(Converter.getDurationStringLong(media.getPosition()));
progressRight.setText(Converter.getDurationStringLong(media.getDuration()));
}
} else {
if (media.getSize() > 0) {
progressLeft.setText(Converter.byteToString(media.getSize()));
} else if (NetworkUtils.isEpisodeHeadDownloadAllowed() && !media.checkedOnSizeButUnknown()) {
progressLeft.setText("{fa-spinner}");
Iconify.addIcons(progressLeft);
NetworkUtils.getFeedMediaSizeObservable(media).subscribe(
size -> {
if (size > 0) {
progressLeft.setText(Converter.byteToString(size));
} else {
progressLeft.setText("");
}
}, error -> {
progressLeft.setText("");
Log.e(TAG, Log.getStackTraceString(error));
});
} else {
progressLeft.setText("");
}
progressRight.setText(Converter.getDurationStringLong(media.getDuration()));
progressBar.setVisibility(View.INVISIBLE);
}
if (media.isCurrentlyPlaying()) {
container.setBackgroundColor(ThemeUtils.getColorFromAttr(activity,
R.attr.currently_playing_background));
} else {
container.setBackgroundColor(Color.TRANSPARENT);
}
}
ItemActionButton actionButton = ItemActionButton.forItem(item, true);
actionButton.configure(butSecondary, activity);
butSecondary.setFocusable(false);
butSecondary.setTag(item);
new CoverLoader(activity)
.withUri(ImageResourceUtils.getImageLocation(item))
.withFallbackUri(item.getFeed().getImageLocation())
.withPlaceholderView(placeholder)
.withCoverView(cover)
.load();
}
private String formatPubDate() {
String pubDateStr = DateUtils.formatAbbrev(activity, item.getPubDate());
int index = 0;
if (countMatches(pubDateStr, ' ') == 1 || countMatches(pubDateStr, ' ') == 2) {
index = pubDateStr.lastIndexOf(' ');
} else if (countMatches(pubDateStr, '.') == 2) {
index = pubDateStr.lastIndexOf('.');
} else if (countMatches(pubDateStr, '-') == 2) {
index = pubDateStr.lastIndexOf('-');
} else if (countMatches(pubDateStr, '/') == 2) {
index = pubDateStr.lastIndexOf('/');
}
if (index > 0) {
pubDateStr = pubDateStr.substring(0, index+1).trim() + "\n" + pubDateStr.substring(index+1);
}
return pubDateStr;
}
public boolean isCurrentlyPlayingItem() {
return item.getMedia() != null && item.getMedia().isCurrentlyPlaying();
}
public void notifyPlaybackPositionUpdated(PlaybackPositionEvent event) {
progressBar.setProgress((int) (100.0 * event.getPosition() / event.getDuration()));
progressLeft.setText(Converter.getDurationStringLong(event.getPosition()));
progressRight.setText(Converter.getDurationStringLong(event.getDuration()));
}
// Oh Xiaomi, I hate you so much. How did you manage to fuck this up?
private static int countMatches(final CharSequence str, final char ch) {
if (TextUtils.isEmpty(str)) {
return 0;
}
int count = 0;
for (int i = 0; i < str.length(); i++) {
if (ch == str.charAt(i)) {
count++;
}
}
return count;
}
}

View File

@ -2,6 +2,7 @@ package de.danoeh.antennapod.core.service.download.handler;
import de.danoeh.antennapod.core.event.DownloadEvent; import de.danoeh.antennapod.core.event.DownloadEvent;
import de.danoeh.antennapod.core.service.download.Downloader; import de.danoeh.antennapod.core.service.download.Downloader;
import de.danoeh.antennapod.core.storage.DownloadRequester;
import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.EventBus;
import java.util.ArrayList; import java.util.ArrayList;
@ -23,6 +24,7 @@ public class PostDownloaderTask implements Runnable {
runningDownloads.add(downloader); runningDownloads.add(downloader);
} }
} }
DownloadRequester.getInstance().updateProgress(downloads);
List<Downloader> list = Collections.unmodifiableList(runningDownloads); List<Downloader> list = Collections.unmodifiableList(runningDownloads);
EventBus.getDefault().postSticky(DownloadEvent.refresh(list)); EventBus.getDefault().postSticky(DownloadEvent.refresh(list));
} }

View File

@ -12,6 +12,7 @@ import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import de.danoeh.antennapod.core.service.download.Downloader;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
import java.io.File; import java.io.File;
@ -343,6 +344,16 @@ public class DownloadRequester implements DownloadStateProvider {
return item.getDownload_url() != null && downloads.containsKey(item.getDownload_url()); return item.getDownload_url() != null && downloads.containsKey(item.getDownload_url());
} }
/**
* Get the downloader for this item.
*/
public synchronized DownloadRequest getRequestFor(FeedFile item) {
if (isDownloadingFile(item)) {
return downloads.get(item.getDownload_url());
}
return null;
}
/** /**
* Checks if feedfile with the given download url is in the downloads list * Checks if feedfile with the given download url is in the downloads list
*/ */
@ -428,4 +439,13 @@ public class DownloadRequester implements DownloadStateProvider {
} }
return filename; return filename;
} }
public void updateProgress(List<Downloader> newDownloads) {
for (Downloader downloader : newDownloads) {
DownloadRequest request = downloader.getDownloadRequest();
if (downloads.containsKey(request.getSource())) {
downloads.put(request.getSource(), request);
}
}
}
} }