| // Copyright (C) 2016 The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package com.google.reviewit; |
| |
| import android.os.AsyncTask; |
| import android.os.Bundle; |
| import android.support.annotation.LayoutRes; |
| import android.support.v4.widget.SwipeRefreshLayout; |
| import android.util.Log; |
| import android.util.TypedValue; |
| import android.view.Menu; |
| import android.view.MenuInflater; |
| import android.view.MenuItem; |
| import android.view.View; |
| import android.view.ViewGroup; |
| import android.view.ViewTreeObserver; |
| import android.widget.ScrollView; |
| import android.widget.TextView; |
| |
| import com.google.gerrit.extensions.restapi.RestApiException; |
| import com.google.reviewit.app.Change; |
| import com.google.reviewit.app.Preferences; |
| import com.google.reviewit.app.QueryHandler; |
| import com.google.reviewit.util.TaskObserver; |
| import com.google.reviewit.widget.ChangeEntry; |
| |
| import java.util.Collections; |
| import java.util.List; |
| |
| import static com.google.reviewit.util.LayoutUtil.matchAndFixedLayout; |
| import static com.google.reviewit.util.WidgetUtil.setGone; |
| import static com.google.reviewit.util.WidgetUtil.setInvisible; |
| import static com.google.reviewit.util.WidgetUtil.setVisible; |
| |
| public class ReviewChangesFragment extends BaseFragment { |
| private static final String TAG = ReviewChangesFragment.class.getName(); |
| |
| @Override |
| protected @LayoutRes int getLayout() { |
| return R.layout.content_review_changes; |
| } |
| |
| @Override |
| public void onActivityCreated(Bundle savedInstanceState) { |
| super.onActivityCreated(savedInstanceState); |
| |
| setTitle(getString(R.string.app_menu_review)); |
| |
| setHasOptionsMenu(true); |
| |
| getApp().getPrefManager().setPreferences( |
| new Preferences.Builder(getApp().getPrefManager().getPreferences()) |
| .setStartScreen(Preferences.StartScreen.REVIEW_SCREEN) |
| .build()); |
| |
| TaskObserver.enableProgressBar(getWindow()); |
| init(); |
| |
| List<Change> loadedChanges = getApp().getQueryHandler().getLoadedChanges(); |
| if (loadedChanges.isEmpty()) { |
| loadAndDisplay(); |
| } else { |
| display(loadedChanges); |
| } |
| } |
| |
| private void init() { |
| SwipeRefreshLayout swipeRefreshLayout = |
| (SwipeRefreshLayout) v(R.id.swipeRefreshLayout); |
| swipeRefreshLayout.setColorSchemeColors(R.color.progressBar); |
| swipeRefreshLayout.setRefreshing(true); |
| swipeRefreshLayout.setOnRefreshListener( |
| new SwipeRefreshLayout.OnRefreshListener() { |
| @Override |
| public void onRefresh() { |
| getApp().getQueryHandler().reset(); |
| loadAndDisplay(true); |
| } |
| }); |
| |
| v(R.id.reloadButton).setOnClickListener(new View.OnClickListener() { |
| public void onClick(View v) { |
| reloadQuery(); |
| } |
| }); |
| |
| final View nextPageProgress = v(R.id.nextPageProgress); |
| final ScrollView scrollView = (ScrollView) v(R.id.scrollView); |
| scrollView.getViewTreeObserver().addOnScrollChangedListener( |
| new ViewTreeObserver.OnScrollChangedListener() { |
| @Override |
| public void onScrollChanged() { |
| if (getApp().getQueryHandler().hasNext() |
| && nextPageProgress.getVisibility() == View.GONE) { |
| View lastChild = |
| scrollView.getChildAt(scrollView.getChildCount() - 1); |
| if ((lastChild.getBottom() |
| - (scrollView.getHeight() + scrollView.getScrollY())) == 0) { |
| setVisible(nextPageProgress); |
| loadAndDisplay(); |
| } |
| } |
| } |
| }); |
| } |
| |
| private void loadAndDisplay() { |
| loadAndDisplay(false); |
| } |
| |
| private void loadAndDisplay(final boolean clear) { |
| if (!isOnline()) { |
| setInvisible(v(R.id.progress)); |
| setGone(v(R.id.initialProgress)); |
| setVisible(v(R.id.statusText, R.id.reloadButton)); |
| TextView statusText = tv(R.id.statusText); |
| statusText.setText(getString(R.string.no_network)); |
| statusText.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15); |
| return; |
| } |
| |
| new AsyncTask<Void, Void, ChangeListData>() { |
| private SwipeRefreshLayout swipeRefreshLayout; |
| private View progress; |
| private View initialProgress; |
| private View nextPageProgress; |
| private View reloadButton; |
| private TextView statusText; |
| private ViewGroup changeList; |
| |
| @Override |
| protected void onPreExecute() { |
| super.onPreExecute(); |
| swipeRefreshLayout = (SwipeRefreshLayout) v(R.id.swipeRefreshLayout); |
| progress = v(R.id.progress); |
| initialProgress = v(R.id.initialProgress); |
| nextPageProgress = v(R.id.nextPageProgress); |
| reloadButton = v(R.id.reloadButton); |
| statusText = tv(R.id.statusText); |
| changeList = vg(R.id.changeList); |
| } |
| |
| @Override |
| protected ChangeListData doInBackground(Void... v) { |
| try { |
| QueryHandler queryHandler = getApp().getQueryHandler(); |
| if (queryHandler.hasNext()) { |
| return new ChangeListData(queryHandler.next()); |
| } else { |
| return new ChangeListData(Collections.<Change>emptyList()); |
| } |
| } catch (RestApiException e) { |
| // e.g. server not reachable |
| Log.e(TAG, "Request failed", e); |
| if (e.getCause() != null) { |
| return new ChangeListData(getString(R.string.error_with_cause, |
| e.getMessage(), e.getCause().getMessage())); |
| } else { |
| return new ChangeListData(e.getMessage()); |
| } |
| } |
| } |
| |
| @Override |
| protected void onPostExecute(ChangeListData changeListData) { |
| super.onPostExecute(changeListData); |
| |
| if (getActivity() == null) { |
| // user navigated away while we were waiting for the request |
| return; |
| } |
| |
| getActivity().invalidateOptionsMenu(); |
| setInvisible(progress); |
| setGone(initialProgress, reloadButton, nextPageProgress); |
| swipeRefreshLayout.setRefreshing(false); |
| |
| if (changeListData.error != null) { |
| statusText.setText(changeListData.error); |
| return; |
| } |
| |
| if (!changeListData.changeList.isEmpty()) { |
| setGone(statusText); |
| if (clear) { |
| changeList.removeAllViews(); |
| } |
| for (Change change : changeListData.changeList) { |
| ChangeEntry changeEntry = new ChangeEntry(getContext()); |
| changeEntry.init(getApp(), change); |
| changeList.addView(changeEntry); |
| addSeparator(changeList); |
| } |
| } else { |
| statusText.setText(getString(R.string.no_changes_match)); |
| } |
| } |
| }.execute(); |
| } |
| |
| private void display(List<Change> changes) { |
| setInvisible(v(R.id.progress)); |
| setGone(v(R.id.initialProgress, R.id.reloadButton, R.id.nextPageProgress, |
| R.id.statusText)); |
| ((SwipeRefreshLayout) v(R.id.swipeRefreshLayout)).setRefreshing(false); |
| ViewGroup changeList = vg(R.id.changeList); |
| for (Change change : changes) { |
| ChangeEntry changeEntry = new ChangeEntry(getContext()); |
| changeEntry.init(ReviewChangesFragment.this, getApp(), change); |
| changeList.addView(changeEntry); |
| addSeparator(changeList); |
| } |
| } |
| |
| private void addSeparator(ViewGroup viewGroup) { |
| View separator = new View(getContext()); |
| separator.setLayoutParams( |
| matchAndFixedLayout(widgetUtil.dpToPx(1))); |
| separator.setBackgroundColor(widgetUtil.color(R.color.separator)); |
| viewGroup.addView(separator); |
| } |
| |
| private void reloadQuery() { |
| getApp().getQueryHandler().reset(); |
| display(getClass(), false); |
| } |
| |
| @Override |
| public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { |
| inflater.inflate(R.menu.menu_review_changes, menu); |
| super.onCreateOptionsMenu(menu, inflater); |
| } |
| |
| @Override |
| public boolean onOptionsItemSelected(MenuItem item) { |
| switch (item.getItemId()) { |
| case R.id.action_reload_query: |
| reloadQuery(); |
| return true; |
| default: |
| return super.onOptionsItemSelected(item); |
| } |
| } |
| |
| private static class ChangeListData { |
| final List<Change> changeList; |
| final String error; |
| |
| ChangeListData(List<Change> changeList) { |
| this.changeList = changeList; |
| this.error = null; |
| } |
| |
| ChangeListData(String error) { |
| this.changeList = null; |
| this.error = error; |
| } |
| } |
| } |