Move download logs to a button on the downloads page instead of a tab (#5866)
This commit is contained in:
parent
dfcc342c57
commit
01bddcc0a9
|
@ -8,9 +8,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
|
|||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.activity.PreferenceActivity;
|
||||
import de.danoeh.antennapod.fragment.CompletedDownloadsFragment;
|
||||
import de.danoeh.antennapod.model.feed.Feed;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.fragment.DownloadsFragment;
|
||||
import de.danoeh.antennapod.fragment.EpisodesFragment;
|
||||
import de.danoeh.antennapod.fragment.NavDrawerFragment;
|
||||
import de.danoeh.antennapod.fragment.PlaybackHistoryFragment;
|
||||
|
@ -154,7 +154,7 @@ public class NavigationDrawerTest {
|
|||
|
||||
@Test
|
||||
public void testDrawerPreferencesUnhideSomeElements() {
|
||||
List<String> hidden = Arrays.asList(PlaybackHistoryFragment.TAG, DownloadsFragment.TAG);
|
||||
List<String> hidden = Arrays.asList(PlaybackHistoryFragment.TAG, CompletedDownloadsFragment.TAG);
|
||||
UserPreferences.setHiddenDrawerItems(hidden);
|
||||
activityRule.launchActivity(new Intent());
|
||||
openNavDrawer();
|
||||
|
@ -211,6 +211,6 @@ public class NavigationDrawerTest {
|
|||
|
||||
List<String> hidden = UserPreferences.getHiddenDrawerItems();
|
||||
assertEquals(1, hidden.size());
|
||||
assertTrue(hidden.contains(DownloadsFragment.TAG));
|
||||
assertTrue(hidden.contains(CompletedDownloadsFragment.TAG));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ import com.bumptech.glide.Glide;
|
|||
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
|
||||
import de.danoeh.antennapod.fragment.CompletedDownloadsFragment;
|
||||
import de.danoeh.antennapod.playback.cast.CastEnabledActivity;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
@ -54,7 +55,6 @@ import de.danoeh.antennapod.core.util.download.AutoUpdateManager;
|
|||
import de.danoeh.antennapod.dialog.RatingDialog;
|
||||
import de.danoeh.antennapod.fragment.AddFeedFragment;
|
||||
import de.danoeh.antennapod.fragment.AudioPlayerFragment;
|
||||
import de.danoeh.antennapod.fragment.DownloadsFragment;
|
||||
import de.danoeh.antennapod.fragment.EpisodesFragment;
|
||||
import de.danoeh.antennapod.fragment.InboxFragment;
|
||||
import de.danoeh.antennapod.fragment.FeedItemlistFragment;
|
||||
|
@ -274,8 +274,8 @@ public class MainActivity extends CastEnabledActivity {
|
|||
case EpisodesFragment.TAG:
|
||||
fragment = new EpisodesFragment();
|
||||
break;
|
||||
case DownloadsFragment.TAG:
|
||||
fragment = new DownloadsFragment();
|
||||
case CompletedDownloadsFragment.TAG:
|
||||
fragment = new CompletedDownloadsFragment();
|
||||
break;
|
||||
case PlaybackHistoryFragment.TAG:
|
||||
fragment = new PlaybackHistoryFragment();
|
||||
|
@ -594,7 +594,7 @@ public class MainActivity extends CastEnabledActivity {
|
|||
}
|
||||
switch (feature) {
|
||||
case "DOWNLOADS":
|
||||
loadFragment(DownloadsFragment.TAG, null);
|
||||
loadFragment(CompletedDownloadsFragment.TAG, null);
|
||||
break;
|
||||
case "HISTORY":
|
||||
loadFragment(PlaybackHistoryFragment.TAG, null);
|
||||
|
|
|
@ -3,26 +3,24 @@ package de.danoeh.antennapod.adapter;
|
|||
import android.app.Activity;
|
||||
import android.text.format.DateUtils;
|
||||
import android.text.format.Formatter;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.util.Log;
|
||||
import android.widget.BaseAdapter;
|
||||
|
||||
import android.widget.Toast;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.ListFragment;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.core.service.download.DownloadRequest;
|
||||
import de.danoeh.antennapod.core.service.download.DownloadRequestCreator;
|
||||
import de.danoeh.antennapod.core.service.download.DownloadService;
|
||||
import de.danoeh.antennapod.core.service.download.Downloader;
|
||||
import de.danoeh.antennapod.core.storage.DBWriter;
|
||||
import de.danoeh.antennapod.model.download.DownloadStatus;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.storage.DBTasks;
|
||||
import de.danoeh.antennapod.model.download.DownloadError;
|
||||
import de.danoeh.antennapod.core.storage.DBWriter;
|
||||
import de.danoeh.antennapod.core.util.DownloadErrorLabel;
|
||||
import de.danoeh.antennapod.model.download.DownloadError;
|
||||
import de.danoeh.antennapod.model.download.DownloadStatus;
|
||||
import de.danoeh.antennapod.model.feed.Feed;
|
||||
import de.danoeh.antennapod.model.feed.FeedItem;
|
||||
import de.danoeh.antennapod.model.feed.FeedMedia;
|
||||
|
@ -39,14 +37,12 @@ public class DownloadLogAdapter extends BaseAdapter {
|
|||
private static final String TAG = "DownloadLogAdapter";
|
||||
|
||||
private final Activity context;
|
||||
private final ListFragment listFragment;
|
||||
private List<DownloadStatus> downloadLog = new ArrayList<>();
|
||||
private List<Downloader> runningDownloads = new ArrayList<>();
|
||||
|
||||
public DownloadLogAdapter(Activity context, ListFragment listFragment) {
|
||||
public DownloadLogAdapter(Activity context) {
|
||||
super();
|
||||
this.context = context;
|
||||
this.listFragment = listFragment;
|
||||
}
|
||||
|
||||
public void setDownloadLog(List<DownloadStatus> downloadLog) {
|
||||
|
|
|
@ -25,13 +25,13 @@ import com.joanzapata.iconify.Iconify;
|
|||
import com.joanzapata.iconify.widget.IconTextView;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.PreferenceActivity;
|
||||
import de.danoeh.antennapod.fragment.CompletedDownloadsFragment;
|
||||
import de.danoeh.antennapod.fragment.InboxFragment;
|
||||
import de.danoeh.antennapod.model.feed.Feed;
|
||||
import de.danoeh.antennapod.core.glide.ApGlideSettings;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.core.storage.NavDrawerData;
|
||||
import de.danoeh.antennapod.fragment.AddFeedFragment;
|
||||
import de.danoeh.antennapod.fragment.DownloadsFragment;
|
||||
import de.danoeh.antennapod.fragment.EpisodesFragment;
|
||||
import de.danoeh.antennapod.fragment.NavDrawerFragment;
|
||||
import de.danoeh.antennapod.fragment.PlaybackHistoryFragment;
|
||||
|
@ -119,7 +119,7 @@ public class NavListAdapter extends RecyclerView.Adapter<NavListAdapter.Holder>
|
|||
return R.drawable.ic_inbox;
|
||||
case EpisodesFragment.TAG:
|
||||
return R.drawable.ic_feed;
|
||||
case DownloadsFragment.TAG:
|
||||
case CompletedDownloadsFragment.TAG:
|
||||
return R.drawable.ic_download;
|
||||
case PlaybackHistoryFragment.TAG:
|
||||
return R.drawable.ic_history;
|
||||
|
@ -257,7 +257,7 @@ public class NavListAdapter extends RecyclerView.Adapter<NavListAdapter.Holder>
|
|||
holder.count.setText(NumberFormat.getInstance().format(sum));
|
||||
holder.count.setVisibility(View.VISIBLE);
|
||||
}
|
||||
} else if (tag.equals(DownloadsFragment.TAG) && UserPreferences.isEnableAutodownload()) {
|
||||
} else if (tag.equals(CompletedDownloadsFragment.TAG) && UserPreferences.isEnableAutodownload()) {
|
||||
int epCacheSize = UserPreferences.getEpisodeCacheSize();
|
||||
// don't count episodes that can be reclaimed
|
||||
int spaceUsed = itemAccess.getNumberOfDownloadedItems()
|
||||
|
|
|
@ -4,14 +4,14 @@ import android.app.PendingIntent;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
||||
import android.os.Bundle;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.DownloadAuthenticationActivity;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.core.DownloadServiceCallbacks;
|
||||
import de.danoeh.antennapod.core.service.download.DownloadRequest;
|
||||
import de.danoeh.antennapod.fragment.DownloadsFragment;
|
||||
import de.danoeh.antennapod.fragment.CompletedDownloadsFragment;
|
||||
import de.danoeh.antennapod.fragment.QueueFragment;
|
||||
|
||||
|
||||
|
@ -20,10 +20,7 @@ public class DownloadServiceCallbacksImpl implements DownloadServiceCallbacks {
|
|||
@Override
|
||||
public PendingIntent getNotificationContentIntent(Context context) {
|
||||
Intent intent = new Intent(context, MainActivity.class);
|
||||
intent.putExtra(MainActivity.EXTRA_FRAGMENT_TAG, DownloadsFragment.TAG);
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(DownloadsFragment.ARG_SELECTED_TAB, DownloadsFragment.POS_LOG);
|
||||
intent.putExtra(MainActivity.EXTRA_FRAGMENT_ARGS, args);
|
||||
intent.putExtra(MainActivity.EXTRA_FRAGMENT_TAG, CompletedDownloadsFragment.TAG);
|
||||
return PendingIntent.getActivity(context,
|
||||
R.id.pending_intent_download_service_notification, intent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT | (Build.VERSION.SDK_INT >= 23 ? PendingIntent.FLAG_IMMUTABLE : 0));
|
||||
|
@ -42,9 +39,9 @@ public class DownloadServiceCallbacksImpl implements DownloadServiceCallbacks {
|
|||
@Override
|
||||
public PendingIntent getReportNotificationContentIntent(Context context) {
|
||||
Intent intent = new Intent(context, MainActivity.class);
|
||||
intent.putExtra(MainActivity.EXTRA_FRAGMENT_TAG, DownloadsFragment.TAG);
|
||||
intent.putExtra(MainActivity.EXTRA_FRAGMENT_TAG, CompletedDownloadsFragment.TAG);
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(DownloadsFragment.ARG_SELECTED_TAB, DownloadsFragment.POS_LOG);
|
||||
args.putBoolean(CompletedDownloadsFragment.ARG_SHOW_LOGS, true);
|
||||
intent.putExtra(MainActivity.EXTRA_FRAGMENT_ARGS, args);
|
||||
return PendingIntent.getActivity(context, R.id.pending_intent_download_service_report, intent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT | (Build.VERSION.SDK_INT >= 23 ? PendingIntent.FLAG_IMMUTABLE : 0));
|
||||
|
|
|
@ -12,30 +12,28 @@ import android.widget.ProgressBar;
|
|||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.util.ObjectsCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.leinardi.android.speeddial.SpeedDialView;
|
||||
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.adapter.EpisodeItemListAdapter;
|
||||
import de.danoeh.antennapod.adapter.actionbutton.DeleteActionButton;
|
||||
import de.danoeh.antennapod.core.event.DownloadEvent;
|
||||
import de.danoeh.antennapod.core.event.DownloadLogEvent;
|
||||
import de.danoeh.antennapod.event.FeedItemEvent;
|
||||
import de.danoeh.antennapod.event.playback.PlaybackPositionEvent;
|
||||
import de.danoeh.antennapod.event.PlayerStatusEvent;
|
||||
import de.danoeh.antennapod.event.UnreadItemsUpdateEvent;
|
||||
import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
|
||||
import de.danoeh.antennapod.fragment.actions.EpisodeMultiSelectActionHandler;
|
||||
import de.danoeh.antennapod.model.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.service.download.DownloadService;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.util.FeedItemUtil;
|
||||
import de.danoeh.antennapod.core.util.download.AutoUpdateManager;
|
||||
import de.danoeh.antennapod.event.FeedItemEvent;
|
||||
import de.danoeh.antennapod.event.PlayerStatusEvent;
|
||||
import de.danoeh.antennapod.event.UnreadItemsUpdateEvent;
|
||||
import de.danoeh.antennapod.event.playback.PlaybackPositionEvent;
|
||||
import de.danoeh.antennapod.fragment.actions.EpisodeMultiSelectActionHandler;
|
||||
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
|
||||
import de.danoeh.antennapod.ui.common.PagedToolbarFragment;
|
||||
import de.danoeh.antennapod.model.feed.FeedItem;
|
||||
import de.danoeh.antennapod.view.EmptyViewHandler;
|
||||
import de.danoeh.antennapod.view.EpisodeItemListRecyclerView;
|
||||
import de.danoeh.antennapod.view.viewholder.EpisodeItemViewHolder;
|
||||
|
@ -53,28 +51,38 @@ import java.util.List;
|
|||
/**
|
||||
* Displays all completed downloads and provides a button to delete them.
|
||||
*/
|
||||
public class CompletedDownloadsFragment extends Fragment implements
|
||||
EpisodeItemListAdapter.OnSelectModeListener {
|
||||
|
||||
private static final String TAG = CompletedDownloadsFragment.class.getSimpleName();
|
||||
public class CompletedDownloadsFragment extends Fragment
|
||||
implements EpisodeItemListAdapter.OnSelectModeListener, Toolbar.OnMenuItemClickListener {
|
||||
public static final String TAG = "DownloadsFragment";
|
||||
public static final String ARG_SHOW_LOGS = "show_logs";
|
||||
private static final String KEY_UP_ARROW = "up_arrow";
|
||||
|
||||
private long[] runningDownloads = new long[0];
|
||||
private List<FeedItem> items = new ArrayList<>();
|
||||
private CompletedDownloadsListAdapter adapter;
|
||||
private EpisodeItemListRecyclerView recyclerView;
|
||||
private ProgressBar progressBar;
|
||||
private Disposable disposable;
|
||||
private EmptyViewHandler emptyView;
|
||||
|
||||
private boolean displayUpArrow;
|
||||
private boolean isUpdatingFeeds = false;
|
||||
|
||||
private SpeedDialView speedDialView;
|
||||
private Toolbar toolbar;
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View root = inflater.inflate(R.layout.simple_list_fragment, container, false);
|
||||
Toolbar toolbar = root.findViewById(R.id.toolbar);
|
||||
toolbar.setVisibility(View.GONE);
|
||||
toolbar = root.findViewById(R.id.toolbar);
|
||||
toolbar.setTitle(R.string.downloads_label);
|
||||
toolbar.inflateMenu(R.menu.downloads_completed);
|
||||
toolbar.setOnMenuItemClickListener(this);
|
||||
refreshToolbarState();
|
||||
displayUpArrow = getParentFragmentManager().getBackStackEntryCount() != 0;
|
||||
if (savedInstanceState != null) {
|
||||
displayUpArrow = savedInstanceState.getBoolean(KEY_UP_ARROW);
|
||||
}
|
||||
((MainActivity) getActivity()).setupToolbarToggle(toolbar, displayUpArrow);
|
||||
|
||||
recyclerView = root.findViewById(R.id.recyclerView);
|
||||
recyclerView.setRecycledViewPool(((MainActivity) getActivity()).getRecycledViewPool());
|
||||
|
@ -82,6 +90,7 @@ public class CompletedDownloadsFragment extends Fragment implements
|
|||
adapter.setOnSelectModeListener(this);
|
||||
recyclerView.setAdapter(adapter);
|
||||
progressBar = root.findViewById(R.id.progLoading);
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
|
||||
speedDialView = root.findViewById(R.id.fabSD);
|
||||
speedDialView.setOverlayLayout(root.findViewById(R.id.fabSDOverlay));
|
||||
|
@ -111,12 +120,21 @@ public class CompletedDownloadsFragment extends Fragment implements
|
|||
adapter.endSelectMode();
|
||||
return true;
|
||||
});
|
||||
if (getArguments() != null && getArguments().getBoolean(ARG_SHOW_LOGS, false)) {
|
||||
new DownloadLogFragment().show(getChildFragmentManager(), null);
|
||||
}
|
||||
|
||||
addEmptyView();
|
||||
EventBus.getDefault().register(this);
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
outState.putBoolean(KEY_UP_ARROW, displayUpArrow);
|
||||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
EventBus.getDefault().unregister(this);
|
||||
|
@ -145,10 +163,16 @@ public class CompletedDownloadsFragment extends Fragment implements
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
if (item.getItemId() == R.id.refresh_item) {
|
||||
AutoUpdateManager.runImmediate(requireContext());
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.action_download_logs) {
|
||||
new DownloadLogFragment().show(getChildFragmentManager(), null);
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.action_search) {
|
||||
((MainActivity) getActivity()).loadChildFragment(SearchFragment.newInstance());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -157,7 +181,20 @@ public class CompletedDownloadsFragment extends Fragment implements
|
|||
public void onEventMainThread(DownloadEvent event) {
|
||||
Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
|
||||
if (event.hasChangedFeedUpdateStatus(isUpdatingFeeds)) {
|
||||
((PagedToolbarFragment) getParentFragment()).invalidateOptionsMenuIfActive(this);
|
||||
refreshToolbarState();
|
||||
}
|
||||
if (!ObjectsCompat.equals(event.update.mediaIds, runningDownloads)) {
|
||||
runningDownloads = event.update.mediaIds;
|
||||
loadItems();
|
||||
return; // Refreshed anyway
|
||||
}
|
||||
if (event.update.mediaIds.length > 0) {
|
||||
for (long mediaId : event.update.mediaIds) {
|
||||
int pos = FeedItemUtil.indexOfItemWithMediaId(items, mediaId);
|
||||
if (pos >= 0) {
|
||||
adapter.notifyItemChangedCompat(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -223,6 +260,11 @@ public class CompletedDownloadsFragment extends Fragment implements
|
|||
}
|
||||
}
|
||||
|
||||
private void refreshToolbarState() {
|
||||
isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(toolbar.getMenu(),
|
||||
R.id.refresh_item, updateRefreshMenuItemChecker);
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onPlayerStatusChanged(PlayerStatusEvent event) {
|
||||
loadItems();
|
||||
|
@ -242,15 +284,28 @@ public class CompletedDownloadsFragment extends Fragment implements
|
|||
if (disposable != null) {
|
||||
disposable.dispose();
|
||||
}
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
emptyView.hide();
|
||||
disposable = Observable.fromCallable(DBReader::getDownloadedItems)
|
||||
disposable = Observable.fromCallable(() -> {
|
||||
List<FeedItem> downloadedItems = DBReader.getDownloadedItems();
|
||||
List<Long> mediaIds = new ArrayList<>();
|
||||
if (runningDownloads == null) {
|
||||
return downloadedItems;
|
||||
}
|
||||
for (long id : runningDownloads) {
|
||||
if (FeedItemUtil.indexOfItemWithMediaId(downloadedItems, id) != -1) {
|
||||
continue; // Already in list
|
||||
}
|
||||
mediaIds.add(id);
|
||||
}
|
||||
List<FeedItem> currentDownloads = DBReader.getFeedItemsWithMedia(mediaIds.toArray(new Long[0]));
|
||||
currentDownloads.addAll(downloadedItems);
|
||||
return currentDownloads;
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(result -> {
|
||||
items = result;
|
||||
adapter.updateItems(result);
|
||||
((PagedToolbarFragment) getParentFragment()).invalidateOptionsMenuIfActive(this);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
}, error -> Log.e(TAG, Log.getStackTraceString(error)));
|
||||
}
|
||||
|
@ -275,10 +330,12 @@ public class CompletedDownloadsFragment extends Fragment implements
|
|||
@Override
|
||||
public void afterBindViewHolder(EpisodeItemViewHolder holder, int pos) {
|
||||
if (!inActionMode()) {
|
||||
if (holder.getFeedItem().isDownloaded()) {
|
||||
DeleteActionButton actionButton = new DeleteActionButton(getItem(pos));
|
||||
actionButton.configure(holder.secondaryActionButton, holder.secondaryActionIcon, getActivity());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
||||
|
|
|
@ -2,27 +2,27 @@ package de.danoeh.antennapod.fragment;
|
|||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.ListView;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.ListFragment;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.adapter.DownloadLogAdapter;
|
||||
import de.danoeh.antennapod.core.event.DownloadEvent;
|
||||
import de.danoeh.antennapod.core.event.DownloadLogEvent;
|
||||
import de.danoeh.antennapod.core.event.DownloaderUpdate;
|
||||
import de.danoeh.antennapod.core.menuhandler.MenuItemUtils;
|
||||
import de.danoeh.antennapod.core.service.download.DownloadService;
|
||||
import de.danoeh.antennapod.model.download.DownloadStatus;
|
||||
import de.danoeh.antennapod.core.service.download.Downloader;
|
||||
import de.danoeh.antennapod.core.storage.DBReader;
|
||||
import de.danoeh.antennapod.core.storage.DBWriter;
|
||||
import de.danoeh.antennapod.core.util.download.AutoUpdateManager;
|
||||
import de.danoeh.antennapod.databinding.DownloadLogFragmentBinding;
|
||||
import de.danoeh.antennapod.dialog.DownloadLogDetailsDialog;
|
||||
import de.danoeh.antennapod.ui.common.PagedToolbarFragment;
|
||||
import de.danoeh.antennapod.model.download.DownloadStatus;
|
||||
import de.danoeh.antennapod.view.EmptyViewHandler;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
|
@ -38,16 +38,15 @@ import java.util.List;
|
|||
/**
|
||||
* Shows the download log
|
||||
*/
|
||||
public class DownloadLogFragment extends ListFragment {
|
||||
|
||||
public class DownloadLogFragment extends BottomSheetDialogFragment
|
||||
implements AdapterView.OnItemClickListener, Toolbar.OnMenuItemClickListener {
|
||||
private static final String TAG = "DownloadLogFragment";
|
||||
|
||||
private List<DownloadStatus> downloadLog = new ArrayList<>();
|
||||
private List<Downloader> runningDownloads = new ArrayList<>();
|
||||
private DownloadLogAdapter adapter;
|
||||
private Disposable disposable;
|
||||
|
||||
private boolean isUpdatingFeeds = false;
|
||||
private DownloadLogFragmentBinding viewBinding;
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
|
@ -63,25 +62,25 @@ public class DownloadLogFragment extends ListFragment {
|
|||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
// add padding
|
||||
final ListView lv = getListView();
|
||||
lv.setClipToPadding(false);
|
||||
final int vertPadding = getResources().getDimensionPixelSize(R.dimen.list_vertical_padding);
|
||||
lv.setPadding(0, vertPadding, 0, vertPadding);
|
||||
setListShown(true);
|
||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||
@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
viewBinding = DownloadLogFragmentBinding.inflate(inflater);
|
||||
viewBinding.toolbar.inflateMenu(R.menu.download_log);
|
||||
viewBinding.toolbar.setOnMenuItemClickListener(this);
|
||||
|
||||
EmptyViewHandler emptyView = new EmptyViewHandler(getActivity());
|
||||
emptyView.setIcon(R.drawable.ic_download);
|
||||
emptyView.setTitle(R.string.no_log_downloads_head_label);
|
||||
emptyView.setMessage(R.string.no_log_downloads_label);
|
||||
emptyView.attachToListView(getListView());
|
||||
emptyView.attachToListView(viewBinding.list);
|
||||
|
||||
adapter = new DownloadLogAdapter(getActivity(), this);
|
||||
setListAdapter(adapter);
|
||||
adapter = new DownloadLogAdapter(getActivity());
|
||||
viewBinding.list.setAdapter(adapter);
|
||||
viewBinding.list.setOnItemClickListener(this);
|
||||
EventBus.getDefault().register(this);
|
||||
return viewBinding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -91,9 +90,7 @@ public class DownloadLogFragment extends ListFragment {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onListItemClick(@NonNull ListView l, @NonNull View v, int position, long id) {
|
||||
super.onListItemClick(l, v, position, id);
|
||||
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
Object item = adapter.getItem(position);
|
||||
if (item instanceof DownloadStatus) {
|
||||
new DownloadLogDetailsDialog(getContext(), (DownloadStatus) item).show();
|
||||
|
@ -108,31 +105,19 @@ public class DownloadLogFragment extends ListFragment {
|
|||
@Override
|
||||
public void onPrepareOptionsMenu(@NonNull Menu menu) {
|
||||
menu.findItem(R.id.clear_logs_item).setVisible(!downloadLog.isEmpty());
|
||||
isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(menu, R.id.refresh_item, updateRefreshMenuItemChecker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
if (super.onOptionsItemSelected(item)) {
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.clear_logs_item) {
|
||||
DBWriter.clearDownloadLog();
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.refresh_item) {
|
||||
AutoUpdateManager.runImmediate(requireContext());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
|
||||
public void onEventMainThread(DownloadEvent event) {
|
||||
Log.d(TAG, "onEventMainThread() called with: " + "event = [" + event + "]");
|
||||
if (event.hasChangedFeedUpdateStatus(isUpdatingFeeds)) {
|
||||
((PagedToolbarFragment) getParentFragment()).invalidateOptionsMenuIfActive(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
|
||||
public void onEvent(DownloadEvent event) {
|
||||
Log.d(TAG, "onEvent() called with: " + "event = [" + event + "]");
|
||||
|
@ -141,9 +126,6 @@ public class DownloadLogFragment extends ListFragment {
|
|||
adapter.setRunningDownloads(runningDownloads);
|
||||
}
|
||||
|
||||
private final MenuItemUtils.UpdateRefreshMenuItemChecker updateRefreshMenuItemChecker =
|
||||
() -> DownloadService.isRunning && DownloadService.isDownloadingFeeds();
|
||||
|
||||
private void loadDownloadLog() {
|
||||
if (disposable != null) {
|
||||
disposable.dispose();
|
||||
|
@ -155,7 +137,6 @@ public class DownloadLogFragment extends ListFragment {
|
|||
if (result != null) {
|
||||
downloadLog = result;
|
||||
adapter.setDownloadLog(downloadLog);
|
||||
((PagedToolbarFragment) getParentFragment()).invalidateOptionsMenuIfActive(this);
|
||||
}
|
||||
}, error -> Log.e(TAG, Log.getStackTraceString(error)));
|
||||
}
|
||||
|
|
|
@ -1,134 +0,0 @@
|
|||
package de.danoeh.antennapod.fragment;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||
import androidx.viewpager2.widget.ViewPager2;
|
||||
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import com.google.android.material.tabs.TabLayoutMediator;
|
||||
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.activity.MainActivity;
|
||||
import de.danoeh.antennapod.ui.common.PagedToolbarFragment;
|
||||
|
||||
/**
|
||||
* Shows the CompletedDownloadsFragment and the RunningDownloadsFragment.
|
||||
*/
|
||||
public class DownloadsFragment extends PagedToolbarFragment {
|
||||
|
||||
public static final String TAG = "DownloadsFragment";
|
||||
|
||||
public static final String ARG_SELECTED_TAB = "selected_tab";
|
||||
private static final String PREF_LAST_TAB_POSITION = "tab_position";
|
||||
private static final String KEY_UP_ARROW = "up_arrow";
|
||||
|
||||
private static final int POS_COMPLETED = 0;
|
||||
public static final int POS_LOG = 1;
|
||||
private static final int TOTAL_COUNT = 2;
|
||||
|
||||
private ViewPager2 viewPager;
|
||||
private TabLayout tabLayout;
|
||||
private boolean displayUpArrow;
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||
@Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
View root = inflater.inflate(R.layout.pager_fragment, container, false);
|
||||
Toolbar toolbar = root.findViewById(R.id.toolbar);
|
||||
toolbar.setTitle(R.string.downloads_label);
|
||||
toolbar.inflateMenu(R.menu.downloads);
|
||||
displayUpArrow = getParentFragmentManager().getBackStackEntryCount() != 0;
|
||||
if (savedInstanceState != null) {
|
||||
displayUpArrow = savedInstanceState.getBoolean(KEY_UP_ARROW);
|
||||
}
|
||||
((MainActivity) getActivity()).setupToolbarToggle(toolbar, displayUpArrow);
|
||||
|
||||
viewPager = root.findViewById(R.id.viewpager);
|
||||
viewPager.setAdapter(new DownloadsPagerAdapter(this));
|
||||
viewPager.setOffscreenPageLimit(2);
|
||||
super.setupPagedToolbar(toolbar, viewPager);
|
||||
|
||||
// Give the TabLayout the ViewPager
|
||||
tabLayout = root.findViewById(R.id.sliding_tabs);
|
||||
new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> {
|
||||
switch (position) {
|
||||
case POS_COMPLETED:
|
||||
tab.setText(R.string.downloads_completed_label);
|
||||
break;
|
||||
case POS_LOG:
|
||||
tab.setText(R.string.downloads_log_label);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}).attach();
|
||||
|
||||
// restore our last position
|
||||
SharedPreferences prefs = getActivity().getSharedPreferences(TAG, Context.MODE_PRIVATE);
|
||||
int lastPosition = prefs.getInt(PREF_LAST_TAB_POSITION, 0);
|
||||
viewPager.setCurrentItem(lastPosition, false);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
outState.putBoolean(KEY_UP_ARROW, displayUpArrow);
|
||||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
if (getArguments() != null) {
|
||||
int tab = getArguments().getInt(ARG_SELECTED_TAB);
|
||||
viewPager.setCurrentItem(tab, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
// save our tab selection
|
||||
SharedPreferences prefs = getActivity().getSharedPreferences(TAG, Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = prefs.edit();
|
||||
editor.putInt(PREF_LAST_TAB_POSITION, tabLayout.getSelectedTabPosition());
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public static class DownloadsPagerAdapter extends FragmentStateAdapter {
|
||||
|
||||
DownloadsPagerAdapter(@NonNull Fragment fragment) {
|
||||
super(fragment);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Fragment createFragment(int position) {
|
||||
switch (position) {
|
||||
case POS_COMPLETED:
|
||||
return new CompletedDownloadsFragment();
|
||||
default:
|
||||
case POS_LOG:
|
||||
return new DownloadLogFragment();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return TOTAL_COUNT;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package de.danoeh.antennapod.fragment;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.LightingColorFilter;
|
||||
import android.os.Bundle;
|
||||
|
@ -514,12 +513,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
|
|||
downloadStatus -> new DownloadLogDetailsDialog(getContext(), downloadStatus).show(),
|
||||
error -> error.printStackTrace(),
|
||||
() -> {
|
||||
Intent intent = new Intent(getContext(), MainActivity.class);
|
||||
intent.putExtra(MainActivity.EXTRA_FRAGMENT_TAG, DownloadsFragment.TAG);
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(DownloadsFragment.ARG_SELECTED_TAB, DownloadsFragment.POS_LOG);
|
||||
intent.putExtra(MainActivity.EXTRA_FRAGMENT_ARGS, args);
|
||||
startActivity(intent);
|
||||
((MainActivity) getActivity()).loadChildFragment(new DownloadLogFragment());
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ public class NavDrawerFragment extends Fragment implements SharedPreferences.OnS
|
|||
InboxFragment.TAG,
|
||||
EpisodesFragment.TAG,
|
||||
SubscriptionFragment.TAG,
|
||||
DownloadsFragment.TAG,
|
||||
CompletedDownloadsFragment.TAG,
|
||||
PlaybackHistoryFragment.TAG,
|
||||
AddFeedFragment.TAG,
|
||||
NavListAdapter.SUBSCRIPTION_LIST_TAG
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:minHeight="300dp">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
android:theme="?attr/actionBarTheme"
|
||||
android:layout_alignParentTop="true"
|
||||
app:title="@string/downloads_log_label" />
|
||||
|
||||
<ListView
|
||||
android:id="@+id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingVertical="@dimen/list_vertical_padding"
|
||||
android:layout_below="@id/toolbar" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progLoading"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:indeterminateOnly="true"
|
||||
android:visibility="gone" />
|
||||
|
||||
</RelativeLayout>
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/clear_logs_item"
|
||||
android:menuCategory="container"
|
||||
android:title="@string/clear_history_label"
|
||||
android:icon="@drawable/ic_delete"
|
||||
app:showAsAction="always" />
|
||||
|
||||
</menu>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/clear_logs_item"
|
||||
android:menuCategory="container"
|
||||
android:title="@string/clear_history_label"
|
||||
android:icon="@drawable/ic_delete"
|
||||
android:visible="false"
|
||||
app:showAsAction="ifRoom" />
|
||||
<item
|
||||
android:id="@+id/refresh_item"
|
||||
android:title="@string/refresh_label"
|
||||
android:menuCategory="container"
|
||||
app:showAsAction="ifRoom"
|
||||
android:icon="@drawable/ic_refresh"/>
|
||||
</menu>
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:custom="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_search"
|
||||
android:icon="@drawable/ic_search"
|
||||
android:title="@string/search_label"
|
||||
custom:showAsAction="always" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_download_logs"
|
||||
android:icon="@drawable/ic_history"
|
||||
android:title="@string/downloads_log_label"
|
||||
custom:showAsAction="always" />
|
||||
|
||||
<item
|
||||
android:id="@+id/refresh_item"
|
||||
android:title="@string/refresh_label"
|
||||
android:menuCategory="container"
|
||||
android:icon="@drawable/ic_refresh"
|
||||
app:showAsAction="always" />
|
||||
|
||||
</menu>
|
|
@ -775,6 +775,19 @@ public final class DBReader {
|
|||
}
|
||||
}
|
||||
|
||||
public static List<FeedItem> getFeedItemsWithMedia(Long[] mediaIds) {
|
||||
PodDBAdapter adapter = PodDBAdapter.getInstance();
|
||||
adapter.open();
|
||||
try (Cursor itemCursor = adapter.getFeedItemCursorByMediaIds(mediaIds)) {
|
||||
List<FeedItem> items = extractItemlistFromCursor(adapter, itemCursor);
|
||||
loadAdditionalFeedItemListData(items);
|
||||
Collections.sort(items, new PlaybackCompletionDateComparator());
|
||||
return items;
|
||||
} finally {
|
||||
adapter.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static class MonthlyStatisticsItem {
|
||||
public int year = 0;
|
||||
public int month = 0;
|
||||
|
|
|
@ -1106,6 +1106,15 @@ public class PodDBAdapter {
|
|||
return db.rawQuery(query, null);
|
||||
}
|
||||
|
||||
public final Cursor getFeedItemCursorByMediaIds(final Long[] ids) {
|
||||
if (ids.length > IN_OPERATOR_MAXIMUM) {
|
||||
throw new IllegalArgumentException("number of IDs must not be larger than " + IN_OPERATOR_MAXIMUM);
|
||||
}
|
||||
final String query = SELECT_FEED_ITEMS_AND_MEDIA
|
||||
+ " WHERE " + SELECT_KEY_MEDIA_ID + " IN (" + TextUtils.join(",", ids) + ")";
|
||||
return db.rawQuery(query, null);
|
||||
}
|
||||
|
||||
public final Cursor getFeedItemCursor(final String guid, final String episodeUrl) {
|
||||
String escapedEpisodeUrl = DatabaseUtils.sqlEscapeString(episodeUrl);
|
||||
String whereClauseCondition = TABLE_NAME_FEED_MEDIA + "." + KEY_DOWNLOAD_URL + "=" + escapedEpisodeUrl;
|
||||
|
|
|
@ -18,8 +18,7 @@
|
|||
<string name="settings_label">Settings</string>
|
||||
<string name="downloads_label">Downloads</string>
|
||||
<string name="open_autodownload_settings">Open Settings</string>
|
||||
<string name="downloads_completed_label">Completed</string>
|
||||
<string name="downloads_log_label">Log</string>
|
||||
<string name="downloads_log_label">Download Log</string>
|
||||
<string name="subscriptions_label">Subscriptions</string>
|
||||
<string name="subscriptions_list_label">Subscriptions List</string>
|
||||
<string name="cancel_download_label">Cancel Download</string>
|
||||
|
|
Loading…
Reference in New Issue