jenkins-bot has submitted this change and it was merged. ( 
https://gerrit.wikimedia.org/r/362096 )

Change subject: Add bulk reading list actions, p. 1
......................................................................


Add bulk reading list actions, p. 1

Puts the basic infrastructure for bulk actions in place and enables
bulk saving for/unsaving from offline.

Bulk adding to another list is a little more involved and is WIP. I'll
submit that later. But since I'm out soon, and in the interest of keeping
patches manageable in size, I thought I'd submit this now.

Bug: T160637
Change-Id: I94db41928afbf86adcb47e7af8133905ac4813eb
---
M app/src/main/java/org/wikipedia/history/HistoryFragment.java
M app/src/main/java/org/wikipedia/main/MainFragment.java
M app/src/main/java/org/wikipedia/page/ExclusiveBottomSheetPresenter.java
M app/src/main/java/org/wikipedia/page/leadimages/PageHeaderView.java
M app/src/main/java/org/wikipedia/readinglist/AddToReadingListDialog.java
M app/src/main/java/org/wikipedia/readinglist/ReadingListFragment.java
M app/src/main/java/org/wikipedia/readinglist/ReadingListItemActionsDialog.java
M app/src/main/java/org/wikipedia/views/MultiSelectActionModeCallback.java
R app/src/main/res/menu/menu_action_mode_history.xml
A app/src/main/res/menu/menu_action_mode_reading_list.xml
M app/src/main/res/values-qq/strings.xml
M app/src/main/res/values/strings.xml
12 files changed, 224 insertions(+), 56 deletions(-)

Approvals:
  Dbrant: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/app/src/main/java/org/wikipedia/history/HistoryFragment.java 
b/app/src/main/java/org/wikipedia/history/HistoryFragment.java
index 2c5b9a8..625957b 100644
--- a/app/src/main/java/org/wikipedia/history/HistoryFragment.java
+++ b/app/src/main/java/org/wikipedia/history/HistoryFragment.java
@@ -508,13 +508,15 @@
     private class MultiSelectCallback extends MultiSelectActionModeCallback {
         @Override
         public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+            super.onCreateActionMode(mode, menu);
+            mode.getMenuInflater().inflate(R.menu.menu_action_mode_history, 
menu);
             actionMode = mode;
             selectedIndices.clear();
             return super.onCreateActionMode(mode, menu);
         }
 
         @Override
-        protected void onDelete() {
+        protected void onDeleteSelected() {
             deleteSelectedPages();
             finishActionMode();
         }
diff --git a/app/src/main/java/org/wikipedia/main/MainFragment.java 
b/app/src/main/java/org/wikipedia/main/MainFragment.java
index 7f6ab17..e075793 100644
--- a/app/src/main/java/org/wikipedia/main/MainFragment.java
+++ b/app/src/main/java/org/wikipedia/main/MainFragment.java
@@ -64,6 +64,7 @@
 import org.wikipedia.util.log.L;
 
 import java.io.File;
+import java.util.Collections;
 import java.util.concurrent.TimeUnit;
 
 import butterknife.BindView;
@@ -248,7 +249,7 @@
                                                       @NonNull final 
FeaturedArticleCard card,
                                                       @NonNull HistoryEntry 
entry) {
         bottomSheetPresenter.show(getChildFragmentManager(),
-                AddToReadingListDialog.newInstance(entry.getTitle(),
+                
AddToReadingListDialog.newInstance(Collections.singletonList(entry.getTitle()),
                         AddToReadingListDialog.InvokeSource.FEED,
                         new DialogInterface.OnDismissListener() {
                             @Override public void onDismiss(DialogInterface 
dialogInterface) {
diff --git 
a/app/src/main/java/org/wikipedia/page/ExclusiveBottomSheetPresenter.java 
b/app/src/main/java/org/wikipedia/page/ExclusiveBottomSheetPresenter.java
index 5693418..7a37cd8 100644
--- a/app/src/main/java/org/wikipedia/page/ExclusiveBottomSheetPresenter.java
+++ b/app/src/main/java/org/wikipedia/page/ExclusiveBottomSheetPresenter.java
@@ -9,19 +9,21 @@
 
 import org.wikipedia.readinglist.AddToReadingListDialog;
 
+import java.util.Collections;
+
 public class ExclusiveBottomSheetPresenter {
     private static final String BOTTOM_SHEET_FRAGMENT_TAG = 
"bottom_sheet_fragment";
     private Dialog currentDialog;
 
     public void showAddToListDialog(@NonNull FragmentManager fm, @NonNull 
PageTitle title,
                                     @NonNull 
AddToReadingListDialog.InvokeSource source) {
-        show(fm, AddToReadingListDialog.newInstance(title, source, null));
+        show(fm, 
AddToReadingListDialog.newInstance(Collections.singletonList(title), source, 
null));
     }
 
     public void showAddToListDialog(@NonNull FragmentManager fm, @NonNull 
PageTitle title,
                                     @NonNull 
AddToReadingListDialog.InvokeSource source,
                                     @Nullable 
DialogInterface.OnDismissListener listener) {
-        show(fm, AddToReadingListDialog.newInstance(title, source, listener));
+        show(fm, 
AddToReadingListDialog.newInstance(Collections.singletonList(title), source, 
listener));
     }
 
     public void show(@NonNull FragmentManager manager, @NonNull DialogFragment 
dialog) {
diff --git 
a/app/src/main/java/org/wikipedia/page/leadimages/PageHeaderView.java 
b/app/src/main/java/org/wikipedia/page/leadimages/PageHeaderView.java
index 9b716f7..264c2a4 100644
--- a/app/src/main/java/org/wikipedia/page/leadimages/PageHeaderView.java
+++ b/app/src/main/java/org/wikipedia/page/leadimages/PageHeaderView.java
@@ -59,8 +59,7 @@
 import static org.wikipedia.util.ResourceUtil.getThemedAttributeId;
 
 public class PageHeaderView extends FrameLayout implements 
ObservableWebView.OnScrollChangeListener {
-    @BindView(R.id.view_page_header_image)
-    PageHeaderImageView image;
+    @BindView(R.id.view_page_header_image) PageHeaderImageView image;
     @BindView(R.id.view_page_header_image_gradient) View gradient;
     @BindView(R.id.view_page_title_text) AppTextView titleText;
     @BindView(R.id.view_page_subtitle_text) AppTextView subtitleText;
diff --git 
a/app/src/main/java/org/wikipedia/readinglist/AddToReadingListDialog.java 
b/app/src/main/java/org/wikipedia/readinglist/AddToReadingListDialog.java
index 157c27f..4648d90 100644
--- a/app/src/main/java/org/wikipedia/readinglist/AddToReadingListDialog.java
+++ b/app/src/main/java/org/wikipedia/readinglist/AddToReadingListDialog.java
@@ -2,6 +2,7 @@
 
 import android.content.DialogInterface;
 import android.os.Bundle;
+import android.os.Parcelable;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.design.widget.BottomSheetBehavior;
@@ -29,6 +30,7 @@
 import org.wikipedia.util.FeedbackUtil;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 public class AddToReadingListDialog extends ExtendedBottomSheetDialogFragment {
@@ -58,7 +60,7 @@
         }
     }
 
-    private PageTitle pageTitle;
+    private List<PageTitle> titles;
     private ReadingListAdapter adapter;
     private View listsContainer;
     private View onboardingContainer;
@@ -70,14 +72,18 @@
     private ReadingListItemCallback listItemCallback = new 
ReadingListItemCallback();
 
     public static AddToReadingListDialog newInstance(@NonNull PageTitle title, 
InvokeSource source) {
-        return newInstance(title, source, null);
+        return newInstance(Collections.singletonList(title), source, null);
     }
 
-    public static AddToReadingListDialog newInstance(@NonNull PageTitle title, 
InvokeSource source,
+    public static AddToReadingListDialog newInstance(@NonNull List<PageTitle> 
titles, InvokeSource source) {
+        return newInstance(titles, source, null);
+    }
+
+    public static AddToReadingListDialog newInstance(@NonNull List<PageTitle> 
titles, InvokeSource source,
                                                      @Nullable 
DialogInterface.OnDismissListener listener) {
         AddToReadingListDialog dialog = new AddToReadingListDialog();
         Bundle args = new Bundle();
-        args.putParcelable("title", title);
+        args.putParcelableArrayList("titles", new 
ArrayList<Parcelable>(titles));
         args.putInt("source", source.code());
         dialog.setArguments(args);
         dialog.setOnDismissListener(listener);
@@ -87,7 +93,7 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        pageTitle = getArguments().getParcelable("title");
+        titles = getArguments().getParcelableArrayList("titles");
         invokeSource = InvokeSource.of(getArguments().getInt("source"));
         adapter = new ReadingListAdapter();
     }
@@ -111,7 +117,7 @@
 
         if (savedInstanceState == null) {
             // Log a click event, but only the first time the dialog is shown.
-            new 
ReadingListsFunnel(pageTitle.getWikiSite()).logAddClick(invokeSource);
+            new ReadingListsFunnel().logAddClick(invokeSource);
         }
 
         updateLists();
@@ -190,13 +196,13 @@
             public void onSuccess(@NonNull CharSequence text) {
                 list.setTitle(text.toString());
                 ReadingList.DAO.addList(list);
-                addAndDismiss(list);
+                addAndDismiss(list, titles);
             }
         }).show();
     }
 
-    private void addAndDismiss(final ReadingList readingList) {
-        final ReadingListPage page = findOrCreatePage(readingList, pageTitle);
+    private void addAndDismiss(final ReadingList readingList, final PageTitle 
title) {
+        final ReadingListPage page = findOrCreatePage(readingList, title);
         ReadingList.DAO.listContainsTitleAsync(readingList, page, new 
CallbackTask.DefaultCallback<Boolean>() {
             @Override public void success(Boolean contains) {
                 if (isAdded()) {
@@ -208,10 +214,9 @@
                                 ? 
getString(R.string.reading_list_added_to_unnamed)
                                 : 
String.format(getString(R.string.reading_list_added_to_named),
                                 readingList.getTitle());
-                        new 
ReadingListsFunnel(pageTitle.getWikiSite()).logAddToList(readingList, 
readingLists.size(), invokeSource);
+                        new 
ReadingListsFunnel(title.getWikiSite()).logAddToList(readingList, 
readingLists.size(), invokeSource);
                         ReadingList.DAO.makeListMostRecent(readingList);
                     }
-
                     showViewListSnackBar(readingList, message);
                     ReadingList.DAO.addTitleToList(readingList, page, false);
                     ReadingListSynchronizer.instance().bumpRevAndSync();
@@ -219,6 +224,40 @@
                 }
             }
         });
+    }
+
+    private void addAndDismiss(final ReadingList readingList, final 
List<PageTitle> titles) {
+        if (titles.size() == 1) {
+            addAndDismiss(readingList, titles.get(0));
+        }
+        /*final Map<String, ReadingListPage> pages = new HashMap<>();
+        for (PageTitle title : titles) {
+            ReadingListPage page = findOrCreatePage(readingList, title);
+            pages.put(page.key(), page);
+        }
+        ReadingList.DAO.titlesNotInListAsync(readingList.key(), new 
ArrayList<>(pages.keySet()),
+                new CallbackTask.DefaultCallback<List<String>>() {
+            @Override public void success(List<String> result) {
+                if (isAdded()) {
+                    String message;
+                    if (result.size() == 0) {
+                        message = "The chosen list already contains all of the 
selected pages."; // todo: string res
+                    } else {
+                        message = TextUtils.isEmpty(readingList.getTitle())
+                                ? String.format("Added %d articles to reading 
list.", result.size()) // todo: string res
+                                : String.format("Added %1$d articles to %2$s", 
result.size(), readingList.getTitle()); // todo: string res
+                        new ReadingListsFunnel().logAddToList(readingList, 
readingLists.size(), invokeSource);
+                        ReadingList.DAO.makeListMostRecent(readingList);
+                    }
+                    showViewListSnackBar(readingList, message);
+                    for (String key : result) {
+                        ReadingList.DAO.addTitleToList(readingList, 
pages.get(key), false);
+                    }
+                    ReadingListSynchronizer.instance().bumpRevAndSync();
+                    dismiss();
+                }
+            }
+        });*/
     }
 
     private void showViewListSnackBar(@NonNull final ReadingList readingList, 
@NonNull String message) {
@@ -242,7 +281,7 @@
     private class ReadingListItemCallback implements 
ReadingListItemView.Callback {
         @Override
         public void onClick(@NonNull ReadingList readingList) {
-            addAndDismiss(readingList);
+            addAndDismiss(readingList, titles);
         }
 
         @Override
diff --git 
a/app/src/main/java/org/wikipedia/readinglist/ReadingListFragment.java 
b/app/src/main/java/org/wikipedia/readinglist/ReadingListFragment.java
index 2b2890e..82e7d44 100644
--- a/app/src/main/java/org/wikipedia/readinglist/ReadingListFragment.java
+++ b/app/src/main/java/org/wikipedia/readinglist/ReadingListFragment.java
@@ -5,6 +5,7 @@
 import android.os.Bundle;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.PluralsRes;
 import android.support.design.widget.AppBarLayout;
 import android.support.design.widget.CollapsingToolbarLayout;
 import android.support.design.widget.Snackbar;
@@ -284,6 +285,13 @@
         update();
     }
 
+    private void 
showMultiSelectOfflineStateChangeSnackbar(List<ReadingListPage> pages, boolean 
offline) {
+        String message = offline
+                ? 
getQuantityString(R.plurals.reading_list_article_offline_message, pages.size())
+                : 
getQuantityString(R.plurals.reading_list_article_not_offline_message, 
pages.size());
+        FeedbackUtil.showMessage(getActivity(), message);
+    }
+
     private void showDeleteItemsUndoSnackbar(final ReadingList readingList, 
final List<ReadingListPage> pages) {
         String message = pages.size() == 1
                 ? String.format(getString(R.string.reading_list_item_deleted), 
pages.get(0).title())
@@ -392,22 +400,72 @@
         adapter.notifyDataSetChanged();
     }
 
-    private void deleteSelectedPages() {
+    @NonNull
+    private List<ReadingListPage> getSelectedPages() {
+        List<ReadingListPage> result = new ArrayList<>();
         if (readingList == null) {
-            return;
+            return result;
         }
-        List<ReadingListPage> selectedPages = new ArrayList<>();
         for (ReadingListPage page : displayedPages) {
             if (page.isSelected()) {
-                selectedPages.add(page);
+                result.add(page);
                 page.setSelected(false);
-                ReadingList.DAO.removeTitleFromList(readingList, page);
             }
         }
+        return result;
+    }
+
+    private void deleteSelectedPages() {
+        List<ReadingListPage> selectedPages = getSelectedPages();
         if (!selectedPages.isEmpty()) {
+            for (ReadingListPage page : selectedPages) {
+                ReadingList.DAO.removeTitleFromList(readingList, page);
+            }
             ReadingListSynchronizer.instance().bumpRevAndSync();
             funnel.logDeleteItem(readingList, readingLists.size());
             showDeleteItemsUndoSnackbar(readingList, selectedPages);
+            update();
+        }
+    }
+
+    private void removeSelectedPagesFromOffline() {
+        List<ReadingListPage> selectedPages = getSelectedPages();
+        if (!selectedPages.isEmpty()) {
+            for (ReadingListPage page : selectedPages) {
+                if (page.isOffline()) {
+                    ReadingListData.instance().setPageOffline(page, false);
+                }
+            }
+            showMultiSelectOfflineStateChangeSnackbar(selectedPages, false);
+            adapter.notifyDataSetChanged();
+            update();
+        }
+    }
+
+    private void saveSelectedPagesForOffline() {
+        List<ReadingListPage> selectedPages = getSelectedPages();
+        if (!selectedPages.isEmpty()) {
+            for (ReadingListPage page : selectedPages) {
+                if (!page.isOffline()) {
+                    ReadingListData.instance().setPageOffline(page, true);
+                }
+            }
+            showMultiSelectOfflineStateChangeSnackbar(selectedPages, true);
+            adapter.notifyDataSetChanged();
+            update();
+        }
+    }
+
+    private void addSelectedPagesToList() {
+        List<ReadingListPage> selectedPages = getSelectedPages();
+        if (!selectedPages.isEmpty()) {
+            List<PageTitle> titles = new ArrayList<>();
+            for (ReadingListPage page : selectedPages) {
+                titles.add(ReadingListDaoProxy.pageTitle(page));
+            }
+            bottomSheetPresenter.show(getChildFragmentManager(),
+                    AddToReadingListDialog.newInstance(titles,
+                            
AddToReadingListDialog.InvokeSource.READING_LIST_ACTIVITY));
             update();
         }
     }
@@ -432,7 +490,7 @@
     }
 
     @Override
-    public void onToggleOffline(int pageIndex) {
+    public void onToggleItemOffline(int pageIndex) {
         ReadingListPage page = readingList == null ? null : 
readingList.get(pageIndex);
         if (page == null) {
             return;
@@ -445,7 +503,7 @@
     }
 
     @Override
-    public void onShare(int pageIndex) {
+    public void onShareItem(int pageIndex) {
         ReadingListPage page = readingList == null ? null : 
readingList.get(pageIndex);
         if (page != null) {
             ShareUtil.shareText(getContext(), 
ReadingListDaoProxy.pageTitle(page));
@@ -453,7 +511,7 @@
     }
 
     @Override
-    public void onAddToOther(int pageIndex) {
+    public void onAddItemToOther(int pageIndex) {
         ReadingListPage page = readingList == null ? null : 
readingList.get(pageIndex);
         if (page != null) {
             bottomSheetPresenter.show(getChildFragmentManager(),
@@ -463,7 +521,7 @@
     }
 
     @Override
-    public void onDelete(int pageIndex) {
+    public void onDeleteItem(int pageIndex) {
         ReadingListPage page = readingList == null ? null : 
readingList.get(pageIndex);
         deleteSinglePage(page);
     }
@@ -472,8 +530,8 @@
         ReadingListData.instance().setPageOffline(page, !page.isOffline());
         if (getActivity() != null) {
             FeedbackUtil.showMessage(getActivity(), page.isOffline()
-                    ? R.string.reading_list_article_offline_message
-                    : R.string.reading_list_article_not_offline_message);
+                    ? 
getQuantityString(R.plurals.reading_list_article_offline_message, 1)
+                    : 
getQuantityString(R.plurals.reading_list_article_not_offline_message, 1));
             adapter.notifyDataSetChanged();
             ReadingListSynchronizer.instance().syncSavedPages();
         }
@@ -503,6 +561,10 @@
             result += "<br>&nbsp;&nbsp;<b>&#8226; " + 
ReadingListDaoProxy.listName(key) + "</b>";
         }
         return StringUtil.fromHtml(result);
+    }
+
+    @NonNull private String getQuantityString(@PluralsRes int id, int 
quantity, Object... formatArgs) {
+        return getResources().getQuantityString(id, quantity, formatArgs);
     }
 
     private class AppBarListener implements 
AppBarLayout.OnOffsetChangedListener {
@@ -693,20 +755,41 @@
     }
 
     private class MultiSelectCallback extends MultiSelectActionModeCallback {
-        @Override
-        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+        @Override public boolean onCreateActionMode(ActionMode mode, Menu 
menu) {
+            super.onCreateActionMode(mode, menu);
+            
mode.getMenuInflater().inflate(R.menu.menu_action_mode_reading_list, menu);
             actionMode = mode;
-            return super.onCreateActionMode(mode, menu);
+            return true;
         }
 
-        @Override
-        protected void onDelete() {
+        @Override public boolean onActionItemClicked(ActionMode mode, MenuItem 
menuItem) {
+            switch (menuItem.getItemId()) {
+                case R.id.menu_delete_selected:
+                    onDeleteSelected();
+                    finishActionMode();
+                    return true;
+                case R.id.menu_remove_from_offline:
+                    removeSelectedPagesFromOffline();
+                    finishActionMode();
+                    return true;
+                case R.id.menu_save_for_offline:
+                    saveSelectedPagesForOffline();
+                    finishActionMode();
+                    return true;
+                case R.id.menu_add_to_another_list:
+                    // addSelectedPagesToList();
+                    finishActionMode();
+                    return true;
+                default:
+            }
+            return false;
+        }
+
+        @Override protected void onDeleteSelected() {
             deleteSelectedPages();
-            finishActionMode();
         }
 
-        @Override
-        public void onDestroyActionMode(ActionMode mode) {
+        @Override public void onDestroyActionMode(ActionMode mode) {
             unselectAllPages();
             actionMode = null;
             super.onDestroyActionMode(mode);
diff --git 
a/app/src/main/java/org/wikipedia/readinglist/ReadingListItemActionsDialog.java 
b/app/src/main/java/org/wikipedia/readinglist/ReadingListItemActionsDialog.java
index 70cce67..309bd4e 100644
--- 
a/app/src/main/java/org/wikipedia/readinglist/ReadingListItemActionsDialog.java
+++ 
b/app/src/main/java/org/wikipedia/readinglist/ReadingListItemActionsDialog.java
@@ -16,10 +16,10 @@
 
 public class ReadingListItemActionsDialog extends 
ExtendedBottomSheetDialogFragment {
     public interface Callback {
-        void onToggleOffline(int pageIndex);
-        void onShare(int pageIndex);
-        void onAddToOther(int pageIndex);
-        void onDelete(int pageIndex);
+        void onToggleItemOffline(int pageIndex);
+        void onShareItem(int pageIndex);
+        void onAddItemToOther(int pageIndex);
+        void onDeleteItem(int pageIndex);
     }
 
     private int pageIndex;
@@ -65,7 +65,7 @@
         public void onToggleOffline() {
             dismiss();
             if (callback() != null) {
-                callback().onToggleOffline(pageIndex);
+                callback().onToggleItemOffline(pageIndex);
             }
         }
 
@@ -73,7 +73,7 @@
         public void onShare() {
             dismiss();
             if (callback() != null) {
-                callback().onShare(pageIndex);
+                callback().onShareItem(pageIndex);
             }
         }
 
@@ -81,7 +81,7 @@
         public void onAddToOther() {
             dismiss();
             if (callback() != null) {
-                callback().onAddToOther(pageIndex);
+                callback().onAddItemToOther(pageIndex);
             }
         }
 
@@ -89,7 +89,7 @@
         public void onDelete() {
             dismiss();
             if (callback() != null) {
-                callback().onDelete(pageIndex);
+                callback().onDeleteItem(pageIndex);
             }
         }
     }
diff --git 
a/app/src/main/java/org/wikipedia/views/MultiSelectActionModeCallback.java 
b/app/src/main/java/org/wikipedia/views/MultiSelectActionModeCallback.java
index acef1ce..a3744d5 100644
--- a/app/src/main/java/org/wikipedia/views/MultiSelectActionModeCallback.java
+++ b/app/src/main/java/org/wikipedia/views/MultiSelectActionModeCallback.java
@@ -17,27 +17,28 @@
     @Override
     public boolean onCreateActionMode(ActionMode mode, Menu menu) {
         mode.setTag(ACTION_MODE_TAG);
-        mode.getMenuInflater().inflate(R.menu.menu_action_mode_multi_select, 
menu);
         return true;
     }
 
-    @Override
-    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+    @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
         return true;
     }
 
-    @Override
-    public boolean onActionItemClicked(ActionMode mode, MenuItem menuItem) {
+    @Override public boolean onActionItemClicked(ActionMode mode, MenuItem 
menuItem) {
         switch (menuItem.getItemId()) {
             case R.id.menu_delete_selected:
-                onDelete();
+                onDeleteSelected();
                 return true;
             default:
         }
         return false;
     }
 
-    protected abstract void onDelete();
+    protected abstract void onDeleteSelected();
+
+    protected String getTag() {
+        return ACTION_MODE_TAG;
+    }
 
     @Override
     public void onDestroyActionMode(ActionMode mode) {
diff --git a/app/src/main/res/menu/menu_action_mode_multi_select.xml 
b/app/src/main/res/menu/menu_action_mode_history.xml
similarity index 100%
rename from app/src/main/res/menu/menu_action_mode_multi_select.xml
rename to app/src/main/res/menu/menu_action_mode_history.xml
diff --git a/app/src/main/res/menu/menu_action_mode_reading_list.xml 
b/app/src/main/res/menu/menu_action_mode_reading_list.xml
new file mode 100644
index 0000000..41d9650
--- /dev/null
+++ b/app/src/main/res/menu/menu_action_mode_reading_list.xml
@@ -0,0 +1,21 @@
+<?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/menu_delete_selected"
+        android:icon="@drawable/ic_delete_white_24dp"
+        android:title="@string/delete_selected_items"
+        app:showAsAction="always" />
+    <item
+        android:id="@+id/menu_remove_from_offline"
+        android:title="@string/reading_list_action_menu_remove_from_offline"
+        app:showAsAction="never" />
+    <item
+        android:id="@+id/menu_save_for_offline"
+        android:title="@string/reading_list_action_menu_save_for_offline"
+        app:showAsAction="never" />
+    <item
+        android:id="@+id/menu_add_to_another_list"
+        android:title="@string/reading_list_action_menu_add_to_another_list"
+        app:showAsAction="never" />
+</menu>
\ No newline at end of file
diff --git a/app/src/main/res/values-qq/strings.xml 
b/app/src/main/res/values-qq/strings.xml
index 5553fca..aae1fde 100644
--- a/app/src/main/res/values-qq/strings.xml
+++ b/app/src/main/res/values-qq/strings.xml
@@ -315,8 +315,14 @@
   <string name="reading_list_article_offline">Label for a toggle switch to 
make a reading list article available offline or online.</string>
   <string name="reading_list_article_make_offline">Hint for button that makes 
a reading list article available for offline use.</string>
   <string name="reading_list_article_remove_offline">Hint for button that 
removes a reading list article from offline availability.</string>
-  <string name="reading_list_article_offline_message">Message shown when a 
reading list article is made available for offline use.</string>
-  <string name="reading_list_article_not_offline_message">Message shown when a 
reading list article is removed from offline availability.</string>
+  <plurals name="reading_list_article_offline_message">
+    <item quantity="one">Message shown when a single reading list article is 
made available for offline use.</item>
+    <item quantity="other">Message shown when more than one reading list 
article is made available for offline use.</item>
+  </plurals>
+  <plurals name="reading_list_article_not_offline_message">
+    <item quantity="one">Message shown when a single reading list article is 
removed from offline availability.</item>
+    <item quantity="other">Message shown when more than one reading list 
article is removed from offline availability.</item>
+  </plurals>
   <string name="reading_list_add_to_other_list">Menu item to add an article to 
another reading list (when the article already exists in one or more 
lists).</string>
   <string name="reading_list_remove_from_list">Menu item to remove an article 
from a specific reading list. The %s symbol is replaced with the name of the 
reading list.</string>
   <string name="reading_list_remove_from_lists">Menu item to remove an article 
from multiple reading lists to which it might belong.</string>
@@ -330,6 +336,10 @@
   <string name="reading_list_login_reminder_text">Text for a tutorial card 
that reminds the user that logging in will enable syncing of reading 
lists.</string>
   <string name="reading_lists_confirm_remote_delete">Warning message shown to 
a user to confirm that remotely stored reading list data used for syncing 
across devices should be deleted.</string>
   <string name="reading_list_article_save_in_progress">Message shown when the 
article is in the process of being downloaded, and is not yet available for 
offline access.</string>
+  <string name="reading_list_action_menu_overflow_label">Label for a menu 
containing actions that may be performed on reading list entries selected by 
the user</string>
+  <string name="reading_list_action_menu_remove_from_offline">Label for a menu 
option allowing the user to remove selected articles from offline 
storage</string>
+  <string name="reading_list_action_menu_save_for_offline">Label for a menu 
option allowing the user to save article content for offline 
availability</string>
+  <string name="reading_list_action_menu_add_to_another_list">Label for a menu 
option allowing the user to add the selected articles to another reading 
list</string>
   <string name="user_option_sync_label">Checkbox title for Wikimedia account 
preference synchronization.\n{{Identical|Preferences}}</string>
   <string name="notification_button_view_user">Button label for navigating to 
the talk page of the user who is the agent of the notification.</string>
   <string name="notification_talk_title">Title for notification when the user 
receives a new message on their Talk page.</string>
diff --git a/app/src/main/res/values/strings.xml 
b/app/src/main/res/values/strings.xml
index 460ccd9..daacc58 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -321,6 +321,10 @@
     <string name="reading_list_menu_delete">Delete list</string>
     <string name="reading_list_menu_rename">Rename</string>
     <string name="reading_list_menu_edit_description">Edit description</string>
+    <string name="reading_list_action_menu_overflow_label">More 
options</string>
+    <string name="reading_list_action_menu_remove_from_offline">Remove from 
offline</string>
+    <string name="reading_list_action_menu_save_for_offline">Save for 
offline</string>
+    <string name="reading_list_action_menu_add_to_another_list">Add to another 
list</string>
     <string name="reading_list_name_sample">My reading list</string>
     <string name="reading_list_name_hint">Name of this list</string>
     <string name="reading_list_description_hint">Description 
(optional)</string>
@@ -341,8 +345,6 @@
     <string name="reading_list_article_offline">Available offline</string>
     <string name="reading_list_article_make_offline">Make this article 
available offline</string>
     <string name="reading_list_article_remove_offline">Don\'t make this 
article available offline</string>
-    <string name="reading_list_article_offline_message">This article will now 
be available offline.</string>
-    <string name="reading_list_article_not_offline_message">This article will 
no longer be available offline.</string>
     <string name="reading_list_add_to_other_list">Add to another reading 
list</string>
     <string name="reading_list_remove_from_list">Remove from %s</string>
     <string name="reading_list_remove_from_lists">Remove from reading 
lists</string>
@@ -356,6 +358,14 @@
     <string name="reading_list_login_reminder_text">Your reading lists may now 
be saved to your Wikipedia account. Simply log in to your account, and your 
reading lists will be synchronized automatically.</string>
     <string name="reading_lists_confirm_remote_delete">This will delete any 
previously synced reading lists from remote storage. Proceed?</string>
     <string name="reading_list_article_save_in_progress">The article is being 
downloaded, and it will be available offline when complete.</string>
+    <plurals name="reading_list_article_offline_message">
+        <item quantity="one">This article will now be available offline.</item>
+        <item quantity="other">These articles will now be available 
offline.</item>
+    </plurals>
+    <plurals name="reading_list_article_not_offline_message">
+        <item quantity="one">This article will no longer be available 
offline.</item>
+        <item quantity="other">These articles will no longer be available 
offline.</item>
+    </plurals>
     <!-- /Reading lists -->
 
     <!-- User options -->

-- 
To view, visit https://gerrit.wikimedia.org/r/362096
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I94db41928afbf86adcb47e7af8133905ac4813eb
Gerrit-PatchSet: 6
Gerrit-Project: apps/android/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Mholloway <[email protected]>
Gerrit-Reviewer: Dbrant <[email protected]>
Gerrit-Reviewer: Mholloway <[email protected]>
Gerrit-Reviewer: Niedzielski <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to