diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java index 2a39321ef..3aeee1c9f 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/QueueRecyclerAdapter.java @@ -1,56 +1,33 @@ 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.view.ContextMenu; -import android.view.LayoutInflater; import android.view.MenuInflater; -import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; -import android.widget.FrameLayout; -import android.widget.ImageButton; -import android.widget.ImageView; -import android.widget.ProgressBar; -import android.widget.TextView; - -import com.joanzapata.iconify.Iconify; - -import de.danoeh.antennapod.core.event.PlaybackPositionEvent; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.view.MotionEventCompat; +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.RecyclerView; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.activity.MainActivity; +import de.danoeh.antennapod.core.feed.FeedItem; +import de.danoeh.antennapod.core.preferences.UserPreferences; +import de.danoeh.antennapod.core.util.LongList; 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 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. */ -public class QueueRecyclerAdapter extends RecyclerView.Adapter { - - private static final String TAG = QueueRecyclerAdapter.class.getSimpleName(); +public class QueueRecyclerAdapter extends RecyclerView.Adapter implements View.OnCreateContextMenuListener { + private static final String TAG = "QueueRecyclerAdapter"; private final WeakReference mainActivity; private final ItemAccess itemAccess; @@ -60,9 +37,6 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter { + if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) { + Log.d(TAG, "startDrag()"); + itemTouchHelper.startDrag(viewHolder); + } + return false; + }); + return viewHolder; } @Override - public void onBindViewHolder(ViewHolder holder, int pos) { + public void onBindViewHolder(EpisodeItemViewHolder holder, int pos) { FeedItem item = itemAccess.getItem(pos); holder.bind(item); + holder.dragHandle.setVisibility(locked ? View.GONE : View.VISIBLE); holder.itemView.setOnLongClickListener(v -> { selectedItem = item; 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 @@ -112,211 +101,30 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter= 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; - }); + menu.setHeaderTitle(selectedItem.getTitle()); + FeedItemMenuHandler.onPrepareMenu(menu, selectedItem, R.id.skip_episode_item); + // Queue-specific menu preparation + final boolean keepSorted = UserPreferences.isQueueKeepSorted(); + final LongList queueAccess = itemAccess.getQueueIds(); + if (queueAccess.size() == 0 || queueAccess.get(0) == selectedItem.getId() || keepSorted) { + menu.findItem(R.id.move_to_top_item).setVisible(false); } - - @Override - 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())); + if (queueAccess.size() == 0 || queueAccess.get(queueAccess.size() - 1) == selectedItem.getId() || keepSorted) { + menu.findItem(R.id.move_to_bottom_item).setVisible(false); } } public interface ItemAccess { FeedItem getItem(int position); + int getCount(); - long getItemDownloadedBytes(FeedItem item); - long getItemDownloadSize(FeedItem item); - int getItemDownloadProgressPercent(FeedItem item); + LongList getQueueIds(); } @@ -341,18 +149,4 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter queue; - private List downloaderList; private boolean isUpdatingFeeds = false; @@ -196,7 +196,6 @@ public class QueueFragment extends Fragment { public void onEventMainThread(DownloadEvent event) { Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]"); DownloaderUpdate update = event.update; - downloaderList = update.downloaders; if (event.hasChangedFeedUpdateStatus(isUpdatingFeeds)) { getActivity().invalidateOptionsMenu(); } @@ -214,7 +213,7 @@ public class QueueFragment extends Fragment { public void onEventMainThread(PlaybackPositionEvent event) { if (recyclerAdapter != null) { for (int i = 0; i < recyclerAdapter.getItemCount(); i++) { - QueueRecyclerAdapter.ViewHolder holder = (QueueRecyclerAdapter.ViewHolder) + EpisodeItemViewHolder holder = (EpisodeItemViewHolder) recyclerView.findViewHolderForAdapterPosition(i); if (holder != null && holder.isCurrentlyPlayingItem()) { holder.notifyPlaybackPositionUpdated(event); @@ -688,46 +687,6 @@ public class QueueFragment extends Fragment { 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 public LongList getQueueIds() { return queue != null ? LongList.of(FeedItemUtil.getIds(queue)) : new LongList(0); diff --git a/app/src/main/java/de/danoeh/antennapod/view/EpisodeItemViewHolder.java b/app/src/main/java/de/danoeh/antennapod/view/EpisodeItemViewHolder.java new file mode 100644 index 000000000..e605ddd06 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/view/EpisodeItemViewHolder.java @@ -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; + } +} diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/PostDownloaderTask.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/PostDownloaderTask.java index 5d2c48679..7c998146d 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/PostDownloaderTask.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/PostDownloaderTask.java @@ -2,6 +2,7 @@ package de.danoeh.antennapod.core.service.download.handler; import de.danoeh.antennapod.core.event.DownloadEvent; import de.danoeh.antennapod.core.service.download.Downloader; +import de.danoeh.antennapod.core.storage.DownloadRequester; import org.greenrobot.eventbus.EventBus; import java.util.ArrayList; @@ -23,6 +24,7 @@ public class PostDownloaderTask implements Runnable { runningDownloads.add(downloader); } } + DownloadRequester.getInstance().updateProgress(downloads); List list = Collections.unmodifiableList(runningDownloads); EventBus.getDefault().postSticky(DownloadEvent.refresh(list)); } diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java index 3d4ee443b..8bd9afe38 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DownloadRequester.java @@ -12,6 +12,7 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.core.content.ContextCompat; +import de.danoeh.antennapod.core.service.download.Downloader; import org.apache.commons.io.FilenameUtils; import java.io.File; @@ -343,6 +344,16 @@ public class DownloadRequester implements DownloadStateProvider { 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 */ @@ -428,4 +439,13 @@ public class DownloadRequester implements DownloadStateProvider { } return filename; } + + public void updateProgress(List newDownloads) { + for (Downloader downloader : newDownloads) { + DownloadRequest request = downloader.getDownloadRequest(); + if (downloads.containsKey(request.getSource())) { + downloads.put(request.getSource(), request); + } + } + } }