Show mark as read rather than mark as played in case item has no media
This commit is contained in:
parent
e1f3452e61
commit
ce659f5cb2
|
@ -64,8 +64,8 @@ public class TextOnlyFeedsTest {
|
|||
openNavDrawer();
|
||||
onDrawerItem(withText(feed.getTitle())).perform(scrollTo(), click());
|
||||
onView(withText(feed.getItemAtIndex(0).getTitle())).perform(click());
|
||||
onView(withText(R.string.mark_read_label)).perform(click());
|
||||
onView(isRoot()).perform(waitForView(allOf(withText(R.string.mark_read_label), not(isDisplayed())), 3000));
|
||||
onView(withText(R.string.mark_read_no_media_label)).perform(click());
|
||||
onView(isRoot()).perform(waitForView(allOf(withText(R.string.mark_read_no_media_label), not(isDisplayed())), 3000));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -273,17 +273,7 @@ public class AllEpisodesRecycleAdapter extends RecyclerView.Adapter<AllEpisodesR
|
|||
if (item != null) {
|
||||
menu.setHeaderTitle(item.getTitle());
|
||||
}
|
||||
|
||||
FeedItemMenuHandler.MenuInterface contextMenuInterface = (id, visible) -> {
|
||||
if (menu == null) {
|
||||
return;
|
||||
}
|
||||
MenuItem item1 = menu.findItem(id);
|
||||
if (item1 != null) {
|
||||
item1.setVisible(visible);
|
||||
}
|
||||
};
|
||||
FeedItemMenuHandler.onPrepareMenu(contextMenuInterface, item);
|
||||
FeedItemMenuHandler.onPrepareMenu(menu, item);
|
||||
}
|
||||
|
||||
public boolean isCurrentlyPlayingItem() {
|
||||
|
|
|
@ -179,26 +179,16 @@ public class QueueRecyclerAdapter extends RecyclerView.Adapter<QueueRecyclerAdap
|
|||
menu.setHeaderTitle(item.getTitle());
|
||||
}
|
||||
|
||||
FeedItemMenuHandler.MenuInterface contextMenuInterface = (id, visible) -> {
|
||||
if (menu == null) {
|
||||
return;
|
||||
}
|
||||
MenuItem item1 = menu.findItem(id);
|
||||
if (item1 != null) {
|
||||
item1.setVisible(visible);
|
||||
}
|
||||
};
|
||||
|
||||
FeedItemMenuHandler.onPrepareMenu(contextMenuInterface, item,
|
||||
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) {
|
||||
contextMenuInterface.setItemVisibility(R.id.move_to_top_item, false);
|
||||
menu.findItem(R.id.move_to_top_item).setVisible(false);
|
||||
}
|
||||
if (queueAccess.size() == 0 || queueAccess.get(queueAccess.size()-1) == item.getId() || keepSorted) {
|
||||
contextMenuInterface.setItemVisibility(R.id.move_to_bottom_item, false);
|
||||
menu.findItem(R.id.move_to_bottom_item).setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ class MarkAsPlayedActionButton extends ItemActionButton {
|
|||
@Override
|
||||
@StringRes
|
||||
public int getLabel() {
|
||||
return R.string.mark_read_label;
|
||||
return (item.hasMedia() ? R.string.mark_read_label : R.string.mark_read_no_media_label);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -116,7 +116,7 @@ public class EpisodesApplyActionFragment extends Fragment {
|
|||
public static EpisodesApplyActionFragment newInstance(List<FeedItem> items, int actions) {
|
||||
EpisodesApplyActionFragment f = new EpisodesApplyActionFragment();
|
||||
f.episodes.addAll(items);
|
||||
for(FeedItem episode : items) {
|
||||
for (FeedItem episode : items) {
|
||||
f.idMap.put(episode.getId(), episode);
|
||||
}
|
||||
f.actions = actions;
|
||||
|
@ -411,7 +411,7 @@ public class EpisodesApplyActionFragment extends Fragment {
|
|||
|
||||
private void refreshTitles() {
|
||||
titles.clear();
|
||||
for(FeedItem episode : episodes) {
|
||||
for (FeedItem episode : episodes) {
|
||||
titles.add(episode.getTitle());
|
||||
}
|
||||
mAdapter.notifyDataSetChanged();
|
||||
|
@ -479,7 +479,7 @@ public class EpisodesApplyActionFragment extends Fragment {
|
|||
private void downloadChecked() {
|
||||
// download the check episodes in the same order as they are currently displayed
|
||||
List<FeedItem> toDownload = new ArrayList<>(checkedIds.size());
|
||||
for(FeedItem episode : episodes) {
|
||||
for (FeedItem episode : episodes) {
|
||||
if(checkedIds.contains(episode.getId()) && episode.hasMedia()) {
|
||||
toDownload.add(episode);
|
||||
}
|
||||
|
@ -494,7 +494,7 @@ public class EpisodesApplyActionFragment extends Fragment {
|
|||
}
|
||||
|
||||
private void deleteChecked() {
|
||||
for(long id : checkedIds.toArray()) {
|
||||
for (long id : checkedIds.toArray()) {
|
||||
FeedItem episode = idMap.get(id);
|
||||
if(episode.hasMedia()) {
|
||||
DBWriter.deleteFeedMediaOfItem(getActivity(), episode.getMedia().getId());
|
||||
|
|
|
@ -290,19 +290,6 @@ public class FeedItemlistFragment extends ListFragment {
|
|||
}
|
||||
}
|
||||
|
||||
private final FeedItemMenuHandler.MenuInterface contextMenuInterface = new FeedItemMenuHandler.MenuInterface() {
|
||||
@Override
|
||||
public void setItemVisibility(int id, boolean visible) {
|
||||
if(contextMenu == null) {
|
||||
return;
|
||||
}
|
||||
MenuItem item = contextMenu.findItem(id);
|
||||
if (item != null) {
|
||||
item.setVisible(visible);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
||||
super.onCreateContextMenu(menu, v, menuInfo);
|
||||
|
@ -320,7 +307,7 @@ public class FeedItemlistFragment extends ListFragment {
|
|||
|
||||
contextMenu = menu;
|
||||
lastMenuInfo = (AdapterView.AdapterContextMenuInfo) menuInfo;
|
||||
FeedItemMenuHandler.onPrepareMenu(contextMenuInterface, item);
|
||||
FeedItemMenuHandler.onPrepareMenu(menu, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -308,7 +308,11 @@ public class ItemFragment extends Fragment {
|
|||
if (media == null) {
|
||||
if (!item.isPlayed()) {
|
||||
butAction1Icon = R.attr.navigation_accept;
|
||||
butAction1Text = R.string.mark_read_label;
|
||||
if (item.hasMedia()) {
|
||||
butAction1Text = R.string.mark_read_label;
|
||||
} else {
|
||||
butAction1Text = R.string.mark_read_no_media_label;
|
||||
}
|
||||
}
|
||||
if (item.getLink() != null) {
|
||||
butAction2Icon = R.attr.location_web_site;
|
||||
|
|
|
@ -140,19 +140,14 @@ public class ItemPagerFragment extends Fragment {
|
|||
}
|
||||
inflater.inflate(R.menu.feeditem_options, menu);
|
||||
|
||||
FeedItemMenuHandler.MenuInterface popupMenuInterface = (id, visible) -> {
|
||||
MenuItem item = menu.findItem(id);
|
||||
if (item != null) {
|
||||
item.setVisible(visible);
|
||||
if (menu != null && item != null) {
|
||||
if (item.hasMedia()) {
|
||||
FeedItemMenuHandler.onPrepareMenu(menu, item);
|
||||
} else {
|
||||
// these are already available via button1 and button2
|
||||
FeedItemMenuHandler.onPrepareMenu(menu, item,
|
||||
R.id.mark_read_item, R.id.visit_website_item);
|
||||
}
|
||||
};
|
||||
|
||||
if (item.hasMedia()) {
|
||||
FeedItemMenuHandler.onPrepareMenu(popupMenuInterface, item);
|
||||
} else {
|
||||
// these are already available via button1 and button2
|
||||
FeedItemMenuHandler.onPrepareMenu(popupMenuInterface, item,
|
||||
R.id.mark_read_item, R.id.visit_website_item);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -550,7 +550,8 @@ public class QueueFragment extends Fragment {
|
|||
final boolean isRead = item.isPlayed();
|
||||
DBWriter.markItemPlayed(FeedItem.PLAYED, false, item.getId());
|
||||
DBWriter.removeQueueItem(getActivity(), true, item);
|
||||
Snackbar snackbar = Snackbar.make(root, getString(R.string.marked_as_read_label), Snackbar.LENGTH_LONG);
|
||||
Snackbar snackbar = Snackbar.make
|
||||
(root, getString(item.hasMedia() ? R.string.marked_as_read_label: R.string.marked_as_read_no_media_label), Snackbar.LENGTH_LONG);
|
||||
snackbar.setAction(getString(R.string.undo), v -> {
|
||||
DBWriter.addQueueItemAt(getActivity(), item.getId(), position, false);
|
||||
if(!isRead) {
|
||||
|
|
|
@ -6,6 +6,8 @@ import androidx.annotation.NonNull;
|
|||
import com.google.android.material.snackbar.Snackbar;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
|
@ -31,94 +33,118 @@ public class FeedItemMenuHandler {
|
|||
private FeedItemMenuHandler() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by the MenuHandler to access different types of menus through one
|
||||
* interface
|
||||
*/
|
||||
public interface MenuInterface {
|
||||
/**
|
||||
* Implementations of this method should call findItem(id) on their
|
||||
* menu-object and call setVisibility(visibility) on the returned
|
||||
* MenuItem object.
|
||||
*/
|
||||
void setItemVisibility(int id, boolean visible);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should be called in the prepare-methods of menus. It changes
|
||||
* the visibility of the menu items depending on a FeedItem's attributes.
|
||||
*
|
||||
* @param mi An instance of MenuInterface that the method uses to change a
|
||||
* MenuItem's visibility
|
||||
* @param menu An instance of Menu
|
||||
* @param selectedItem The FeedItem for which the menu is supposed to be prepared
|
||||
* @return Returns true if selectedItem is not null.
|
||||
*/
|
||||
public static boolean onPrepareMenu(MenuInterface mi,
|
||||
public static boolean onPrepareMenu(Menu menu,
|
||||
FeedItem selectedItem) {
|
||||
if (selectedItem == null) {
|
||||
if (menu == null || selectedItem == null) {
|
||||
return false;
|
||||
}
|
||||
boolean hasMedia = selectedItem.getMedia() != null;
|
||||
boolean isPlaying = hasMedia && selectedItem.getState() == FeedItem.State.PLAYING;
|
||||
|
||||
if (!isPlaying) {
|
||||
mi.setItemVisibility(R.id.skip_episode_item, false);
|
||||
setItemVisibility(menu, R.id.skip_episode_item, false);
|
||||
}
|
||||
|
||||
boolean isInQueue = selectedItem.isTagged(FeedItem.TAG_QUEUE);
|
||||
if (!isInQueue) {
|
||||
mi.setItemVisibility(R.id.remove_from_queue_item, false);
|
||||
setItemVisibility(menu, R.id.remove_from_queue_item, false);
|
||||
}
|
||||
if (!(!isInQueue && selectedItem.getMedia() != null)) {
|
||||
mi.setItemVisibility(R.id.add_to_queue_item, false);
|
||||
setItemVisibility(menu, R.id.add_to_queue_item, false);
|
||||
}
|
||||
|
||||
if (!ShareUtils.hasLinkToShare(selectedItem)) {
|
||||
mi.setItemVisibility(R.id.visit_website_item, false);
|
||||
mi.setItemVisibility(R.id.share_link_item, false);
|
||||
mi.setItemVisibility(R.id.share_link_with_position_item, false);
|
||||
setItemVisibility(menu, R.id.visit_website_item, false);
|
||||
setItemVisibility(menu, R.id.share_link_item, false);
|
||||
setItemVisibility(menu, R.id.share_link_with_position_item, false);
|
||||
}
|
||||
if (!hasMedia || selectedItem.getMedia().getDownload_url() == null) {
|
||||
mi.setItemVisibility(R.id.share_download_url_item, false);
|
||||
mi.setItemVisibility(R.id.share_download_url_with_position_item, false);
|
||||
setItemVisibility(menu, R.id.share_download_url_item, false);
|
||||
setItemVisibility(menu, R.id.share_download_url_with_position_item, false);
|
||||
}
|
||||
if(!hasMedia || selectedItem.getMedia().getPosition() <= 0) {
|
||||
mi.setItemVisibility(R.id.share_link_with_position_item, false);
|
||||
mi.setItemVisibility(R.id.share_download_url_with_position_item, false);
|
||||
setItemVisibility(menu, R.id.share_download_url_with_position_item, false);
|
||||
setItemVisibility(menu, R.id.share_link_with_position_item, false);
|
||||
}
|
||||
|
||||
boolean fileDownloaded = hasMedia && selectedItem.getMedia().fileExists();
|
||||
mi.setItemVisibility(R.id.share_file, fileDownloaded);
|
||||
setItemVisibility(menu, R.id.share_file, fileDownloaded);
|
||||
|
||||
mi.setItemVisibility(R.id.remove_new_flag_item, selectedItem.isNew());
|
||||
setItemVisibility(menu, R.id.remove_new_flag_item, selectedItem.isNew());
|
||||
if (selectedItem.isPlayed()) {
|
||||
mi.setItemVisibility(R.id.mark_read_item, false);
|
||||
setItemVisibility(menu, R.id.mark_read_item, false);
|
||||
} else {
|
||||
mi.setItemVisibility(R.id.mark_unread_item, false);
|
||||
setItemVisibility(menu, R.id.mark_unread_item, false);
|
||||
}
|
||||
|
||||
if(selectedItem.getMedia() == null || selectedItem.getMedia().getPosition() == 0) {
|
||||
mi.setItemVisibility(R.id.reset_position, false);
|
||||
if (selectedItem.getMedia() == null || selectedItem.getMedia().getPosition() == 0) {
|
||||
setItemVisibility(menu, R.id.reset_position, false);
|
||||
}
|
||||
|
||||
if(!UserPreferences.isEnableAutodownload() || fileDownloaded) {
|
||||
mi.setItemVisibility(R.id.activate_auto_download, false);
|
||||
mi.setItemVisibility(R.id.deactivate_auto_download, false);
|
||||
} else if(selectedItem.getAutoDownload()) {
|
||||
mi.setItemVisibility(R.id.activate_auto_download, false);
|
||||
setItemVisibility(menu, R.id.activate_auto_download, false);
|
||||
setItemVisibility(menu, R.id.deactivate_auto_download, false);
|
||||
} else if (selectedItem.getAutoDownload()) {
|
||||
setItemVisibility(menu, R.id.activate_auto_download, false);
|
||||
} else {
|
||||
mi.setItemVisibility(R.id.deactivate_auto_download, false);
|
||||
setItemVisibility(menu, R.id.deactivate_auto_download, false);
|
||||
}
|
||||
|
||||
// Display proper strings when item has no media
|
||||
if (!hasMedia && !selectedItem.isPlayed()) {
|
||||
setItemTitle(menu, R.id.mark_read_item, R.string.mark_read_no_media_label);
|
||||
}
|
||||
|
||||
if (!hasMedia && selectedItem.isPlayed()) {
|
||||
setItemTitle(menu, R.id.mark_unread_item, R.string.mark_unread_label_no_media);
|
||||
}
|
||||
|
||||
boolean isFavorite = selectedItem.isTagged(FeedItem.TAG_FAVORITE);
|
||||
mi.setItemVisibility(R.id.add_to_favorites_item, !isFavorite);
|
||||
mi.setItemVisibility(R.id.remove_from_favorites_item, isFavorite);
|
||||
setItemVisibility(menu, R.id.add_to_favorites_item, !isFavorite);
|
||||
setItemVisibility(menu, R.id.remove_from_favorites_item, isFavorite);
|
||||
|
||||
mi.setItemVisibility(R.id.remove_item, fileDownloaded);
|
||||
setItemVisibility(menu, R.id.remove_item, fileDownloaded);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to set the viability of a menu item.
|
||||
* This method also does some null-checking so that neither menu nor the menu item are null
|
||||
* in order to prevent nullpointer exceptions.
|
||||
* @param menu The menu that should be used
|
||||
* @param menuId The id of the menu item that will be used
|
||||
* @param visibility The new visibility status of given menu item
|
||||
* */
|
||||
private static void setItemVisibility(Menu menu, int menuId, boolean visibility) {
|
||||
if (menu == null) {
|
||||
return;
|
||||
}
|
||||
MenuItem item = menu.findItem(menuId);
|
||||
if (item != null) {
|
||||
item.setVisible(visibility);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method allows to replace to String of a menu item with a different one.
|
||||
* @param menu Menu item that should be used
|
||||
* @param id The id of the string that is going to be replaced.
|
||||
* @param noMedia The id of the new String that is going to be used.
|
||||
* */
|
||||
public static void setItemTitle(Menu menu, int id, int noMedia){
|
||||
MenuItem item = menu.findItem(id);
|
||||
if (item != null) {
|
||||
item.setTitle(noMedia);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The same method as onPrepareMenu(MenuInterface, FeedItem, boolean, QueueAccess), but lets the
|
||||
* caller also specify a list of menu items that should not be shown.
|
||||
|
@ -126,13 +152,16 @@ public class FeedItemMenuHandler {
|
|||
* @param excludeIds Menu item that should be excluded
|
||||
* @return true if selectedItem is not null.
|
||||
*/
|
||||
public static boolean onPrepareMenu(MenuInterface mi,
|
||||
public static boolean onPrepareMenu(Menu menu,
|
||||
FeedItem selectedItem,
|
||||
int... excludeIds) {
|
||||
boolean rc = onPrepareMenu(mi, selectedItem);
|
||||
if (menu == null || selectedItem == null ) {
|
||||
return false;
|
||||
}
|
||||
boolean rc = onPrepareMenu(menu, selectedItem);
|
||||
if (rc && excludeIds != null) {
|
||||
for (int id : excludeIds) {
|
||||
mi.setItemVisibility(id, false);
|
||||
setItemVisibility(menu, id, false);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
|
@ -161,7 +190,7 @@ public class FeedItemMenuHandler {
|
|||
case R.id.mark_read_item:
|
||||
selectedItem.setPlayed(true);
|
||||
DBWriter.markItemPlayed(selectedItem, FeedItem.PLAYED, true);
|
||||
if(GpodnetPreferences.loggedIn()) {
|
||||
if (GpodnetPreferences.loggedIn()) {
|
||||
FeedMedia media = selectedItem.getMedia();
|
||||
// not all items have media, Gpodder only cares about those that do
|
||||
if (media != null) {
|
||||
|
@ -179,7 +208,7 @@ public class FeedItemMenuHandler {
|
|||
case R.id.mark_unread_item:
|
||||
selectedItem.setPlayed(false);
|
||||
DBWriter.markItemPlayed(selectedItem, FeedItem.UNPLAYED, false);
|
||||
if(GpodnetPreferences.loggedIn() && selectedItem.getMedia() != null) {
|
||||
if (GpodnetPreferences.loggedIn() && selectedItem.getMedia() != null) {
|
||||
GpodnetEpisodeAction actionNew = new GpodnetEpisodeAction.Builder(selectedItem, Action.NEW)
|
||||
.currentDeviceId()
|
||||
.currentTimestamp()
|
||||
|
|
|
@ -179,11 +179,14 @@
|
|||
<string name="removed_new_flag_label">Removed \"new\" flag</string>
|
||||
<string name="mark_read_label">Mark as played</string>
|
||||
<string name="marked_as_read_label">Marked as played</string>
|
||||
<string name="mark_read_no_media_label">Mark as read</string>
|
||||
<string name="marked_as_read_no_media_label">Marked as read</string>
|
||||
<plurals name="marked_read_batch_label">
|
||||
<item quantity="one">%d episode marked as played.</item>
|
||||
<item quantity="other">%d episodes marked as played.</item>
|
||||
</plurals>
|
||||
<string name="mark_unread_label">Mark as unplayed</string>
|
||||
<string name="mark_unread_label_no_media">Mark as unread</string>
|
||||
<plurals name="marked_unread_batch_label">
|
||||
<item quantity="one">%d episode marked as unplayed.</item>
|
||||
<item quantity="other">%d episodes marked as unplayed.</item>
|
||||
|
|
Loading…
Reference in New Issue