jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/367705 )
Change subject: Populate remote compilations with response from CompilationClient. ...................................................................... Populate remote compilations with response from CompilationClient. Upon receiving the payload from CompilationClient, this also updates the user's local compilations with any updated metadata from the remote compilations (matched on the file name of each compilation). Bug: T163588 Bug: T163590 Change-Id: I77bc69be5e80b39939b34c41d8dc184ab07f8e39 --- M app/src/main/java/org/wikipedia/offline/CompilationClient.java M app/src/main/java/org/wikipedia/offline/LocalCompilationsFragment.java M app/src/main/java/org/wikipedia/offline/OfflineManager.java M app/src/main/java/org/wikipedia/offline/RemoteCompilationsFragment.java M app/src/main/res/layout/fragment_remote_compilations.xml 5 files changed, 239 insertions(+), 11 deletions(-) Approvals: jenkins-bot: Verified Mholloway: Looks good to me, approved diff --git a/app/src/main/java/org/wikipedia/offline/CompilationClient.java b/app/src/main/java/org/wikipedia/offline/CompilationClient.java index 395d3db..54c0868 100644 --- a/app/src/main/java/org/wikipedia/offline/CompilationClient.java +++ b/app/src/main/java/org/wikipedia/offline/CompilationClient.java @@ -1,6 +1,5 @@ package org.wikipedia.offline; - import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.VisibleForTesting; diff --git a/app/src/main/java/org/wikipedia/offline/LocalCompilationsFragment.java b/app/src/main/java/org/wikipedia/offline/LocalCompilationsFragment.java index d243061..ca13c34 100644 --- a/app/src/main/java/org/wikipedia/offline/LocalCompilationsFragment.java +++ b/app/src/main/java/org/wikipedia/offline/LocalCompilationsFragment.java @@ -95,6 +95,12 @@ } @Override + public void onResume() { + adapter.notifyDataSetChanged(); + super.onResume(); + } + + @Override public void onDestroyView() { recyclerView.setAdapter(null); unbinder.unbind(); @@ -207,7 +213,7 @@ getView().setItem(compilation); getView().setTitle(compilation.name()); getView().setDescription(compilation.description()); - //TODO: getView().setImageUrl( ... ); + getView().setImageUrl(compilation.thumbUri() == null ? null : compilation.thumbUri().toString()); getView().setActionIcon(R.drawable.ic_more_vert_white_24dp); getView().setActionHint(R.string.abc_action_menu_overflow_description); } diff --git a/app/src/main/java/org/wikipedia/offline/OfflineManager.java b/app/src/main/java/org/wikipedia/offline/OfflineManager.java index f352a5b..aeba0a7 100644 --- a/app/src/main/java/org/wikipedia/offline/OfflineManager.java +++ b/app/src/main/java/org/wikipedia/offline/OfflineManager.java @@ -79,6 +79,18 @@ searchTask.execute(); } + void updateFromRemoteMetadata(@NonNull List<Compilation> remoteCompilations) { + for (Compilation remoteCompilation : remoteCompilations) { + for (Compilation localCompilation : compilations) { + if (remoteCompilation.uri() != null + && new File(localCompilation.path()).getName().equals(remoteCompilation.uri().getLastPathSegment())) { + localCompilation.copyMetadataFrom(remoteCompilation); + } + } + } + Prefs.setCompilationCache(compilations); + } + public boolean titleExists(@NonNull String title) { for (Compilation c : compilations) { if (c.titleExists(title)) { diff --git a/app/src/main/java/org/wikipedia/offline/RemoteCompilationsFragment.java b/app/src/main/java/org/wikipedia/offline/RemoteCompilationsFragment.java index 682f280..60120aa 100644 --- a/app/src/main/java/org/wikipedia/offline/RemoteCompilationsFragment.java +++ b/app/src/main/java/org/wikipedia/offline/RemoteCompilationsFragment.java @@ -4,20 +4,35 @@ import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.design.widget.AppBarLayout; import android.support.design.widget.CollapsingToolbarLayout; import android.support.v4.app.Fragment; import android.support.v7.app.AppCompatActivity; +import android.support.v7.view.ActionMode; +import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; +import android.text.TextUtils; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.widget.ProgressBar; import org.wikipedia.R; +import org.wikipedia.WikipediaApp; +import org.wikipedia.history.SearchActionModeCallback; +import org.wikipedia.util.ResourceUtil; +import org.wikipedia.views.DefaultViewHolder; +import org.wikipedia.views.DrawableItemDecoration; +import org.wikipedia.views.PageItemView; import org.wikipedia.views.SearchEmptyView; +import org.wikipedia.views.WikiErrorView; + +import java.util.ArrayList; +import java.util.List; import butterknife.BindView; import butterknife.ButterKnife; @@ -25,10 +40,24 @@ public class RemoteCompilationsFragment extends Fragment { @BindView(R.id.compilation_list_toolbar_container) CollapsingToolbarLayout toolbarLayout; + @BindView(R.id.compilation_list_app_bar) AppBarLayout appBarLayout; @BindView(R.id.compilation_list_toolbar) Toolbar toolbar; @BindView(R.id.compilation_list_contents) RecyclerView recyclerView; @BindView(R.id.search_empty_view) SearchEmptyView searchEmptyView; + @BindView(R.id.compilation_list_progress) ProgressBar progressBar; + @BindView(R.id.compilation_list_error) WikiErrorView errorView; private Unbinder unbinder; + + private boolean updating; + private Throwable lastError; + private CompilationCallback compilationCallback = new CompilationCallback(); + private CompilationItemAdapter adapter = new CompilationItemAdapter(); + private ItemCallback itemCallback = new ItemCallback(); + + private SearchCallback searchActionModeCallback = new SearchCallback(); + @NonNull private List<Compilation> allItems = new ArrayList<>(); + @NonNull private List<Compilation> displayedItems = new ArrayList<>(); + private String currentSearchQuery; @NonNull public static RemoteCompilationsFragment newInstance() { @@ -49,6 +78,27 @@ getAppCompatActivity().setSupportActionBar(toolbar); getAppCompatActivity().getSupportActionBar().setDisplayHomeAsUpEnabled(true); getAppCompatActivity().getSupportActionBar().setTitle(""); + + recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + recyclerView.setAdapter(adapter); + recyclerView.addItemDecoration(new DrawableItemDecoration(getContext(), + ResourceUtil.getThemedAttributeId(getContext(), R.attr.list_separator_drawable), true)); + + errorView.setRetryClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + beginUpdate(); + } + }); + + errorView.setBackClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getActivity().finish(); + } + }); + + beginUpdate(); return view; } @@ -75,13 +125,171 @@ public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menu_search_compilations: - // TODO + ((AppCompatActivity) getActivity()).startSupportActionMode(searchActionModeCallback); return true; default: return super.onOptionsItemSelected(item); } } + private void beginUpdate() { + updating = true; + lastError = null; + new CompilationClient().request(WikipediaApp.getInstance().getWikiSite(), compilationCallback); + updateEmptyState(); + } + + private void setSearchQuery(@Nullable String query) { + currentSearchQuery = query; + displayedItems.clear(); + if (TextUtils.isEmpty(query)) { + displayedItems.addAll(allItems); + } else { + query = query.toUpperCase(); + for (Compilation c : allItems) { + if (c.name().toUpperCase().contains(query.toUpperCase())) { + displayedItems.add(c); + } + } + } + adapter.notifyDataSetChanged(); + updateEmptyState(query); + } + + private void updateEmptyState() { + updateEmptyState(currentSearchQuery); + } + + private void updateEmptyState(@Nullable String searchQuery) { + progressBar.setVisibility(updating ? View.VISIBLE : View.GONE); + if (lastError != null) { + errorView.setError(lastError); + errorView.setVisibility(View.VISIBLE); + searchEmptyView.setVisibility(View.GONE); + recyclerView.setVisibility(View.GONE); + return; + } + errorView.setVisibility(View.GONE); + if (TextUtils.isEmpty(searchQuery)) { + searchEmptyView.setVisibility(View.GONE); + recyclerView.setVisibility(View.VISIBLE); + } else { + recyclerView.setVisibility(displayedItems.isEmpty() ? View.GONE : View.VISIBLE); + searchEmptyView.setVisibility(displayedItems.isEmpty() ? View.VISIBLE : View.GONE); + } + } + + private class CompilationItemHolder extends DefaultViewHolder<PageItemView<Compilation>> { + private Compilation compilation; + + CompilationItemHolder(PageItemView<Compilation> itemView) { + super(itemView); + } + + void bindItem(Compilation compilation) { + this.compilation = compilation; + getView().setItem(compilation); + getView().setTitle(compilation.name()); + getView().setDescription(compilation.description()); + getView().setImageUrl(compilation.thumbUri() == null ? null : compilation.thumbUri().toString()); + getView().setActionIcon(R.drawable.ic_more_vert_white_24dp); + getView().setActionHint(R.string.abc_action_menu_overflow_description); + } + } + + private final class CompilationItemAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { + @Override + public int getItemCount() { + return displayedItems.size(); + } + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int type) { + return new CompilationItemHolder(new PageItemView<Compilation>(getContext())); + } + + @Override + public void onBindViewHolder(RecyclerView.ViewHolder holder, int pos) { + ((CompilationItemHolder) holder).bindItem(displayedItems.get(pos)); + } + + @Override public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) { + super.onViewAttachedToWindow(holder); + ((CompilationItemHolder) holder).getView().setCallback(itemCallback); + } + + @Override public void onViewDetachedFromWindow(RecyclerView.ViewHolder holder) { + ((CompilationItemHolder) holder).getView().setCallback(null); + super.onViewDetachedFromWindow(holder); + } + } + + private class ItemCallback implements PageItemView.Callback<Compilation> { + @Override + public void onClick(@Nullable Compilation item) { + startActivity(CompilationDetailActivity.newIntent(getContext())); + } + + @Override + public boolean onLongClick(@Nullable Compilation item) { + return true; + } + + @Override + public void onThumbClick(@Nullable Compilation item) { + onClick(item); + } + + @Override + public void onActionClick(@Nullable Compilation item, @NonNull PageItemView view) { + } + + @Override + public void onSecondaryActionClick(@Nullable Compilation item, @NonNull PageItemView view) { + } + } + + private class SearchCallback extends SearchActionModeCallback { + @Override + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + appBarLayout.setExpanded(false, true); + return super.onCreateActionMode(mode, menu); + } + + @Override + protected void onQueryChange(String s) { + setSearchQuery(s); + } + + @Override + public void onDestroyActionMode(ActionMode mode) { + super.onDestroyActionMode(mode); + setSearchQuery(null); + } + + @Override + protected String getSearchHintString() { + return getString(R.string.offline_compilations_search_by_name); + } + } + + private class CompilationCallback implements CompilationClient.Callback { + @Override + public void success(@NonNull List<Compilation> compilations) { + allItems = compilations; + updating = false; + OfflineManager.instance().updateFromRemoteMetadata(compilations); + setSearchQuery(currentSearchQuery); + } + + @Override + public void error(@NonNull Throwable caught) { + updating = false; + lastError = caught; + updateEmptyState(); + } + } + private AppCompatActivity getAppCompatActivity() { return (AppCompatActivity) getActivity(); } diff --git a/app/src/main/res/layout/fragment_remote_compilations.xml b/app/src/main/res/layout/fragment_remote_compilations.xml index 2824f2d..24a120a 100644 --- a/app/src/main/res/layout/fragment_remote_compilations.xml +++ b/app/src/main/res/layout/fragment_remote_compilations.xml @@ -85,16 +85,19 @@ android:layout_height="match_parent" android:background="?attr/window_background_color"/> - <TextView - android:id="@+id/compilation_list_empty_text" + <ProgressBar + android:id="@+id/compilation_list_progress" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_horizontal" + android:layout_marginTop="48dp"/> + + <org.wikipedia.views.WikiErrorView + android:id="@+id/compilation_list_error" android:layout_width="match_parent" android:layout_height="wrap_content" - android:gravity="center" - android:padding="16dp" - android:textSize="16sp" - android:text="@string/reading_list_empty" - android:visibility="gone" - tools:visibility="gone"/> + android:layout_gravity="center_horizontal" + android:orientation="vertical"/> <org.wikipedia.views.SearchEmptyView android:id="@+id/search_empty_view" -- To view, visit https://gerrit.wikimedia.org/r/367705 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I77bc69be5e80b39939b34c41d8dc184ab07f8e39 Gerrit-PatchSet: 9 Gerrit-Project: apps/android/wikipedia Gerrit-Branch: master Gerrit-Owner: Dbrant <dbr...@wikimedia.org> Gerrit-Reviewer: Brion VIBBER <br...@wikimedia.org> Gerrit-Reviewer: Mholloway <mhollo...@wikimedia.org> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits