/*
* Copyright (c) 2015 Ha Duy Trung
*
* 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 io.github.hidroh.materialistic;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import javax.inject.Inject;
import javax.inject.Named;
import io.github.hidroh.materialistic.annotation.Synthetic;
import io.github.hidroh.materialistic.data.AlgoliaClient;
import io.github.hidroh.materialistic.data.AlgoliaPopularClient;
import io.github.hidroh.materialistic.data.Item;
import io.github.hidroh.materialistic.data.ItemManager;
import io.github.hidroh.materialistic.data.ResponseListener;
import io.github.hidroh.materialistic.widget.ListRecyclerViewAdapter;
import io.github.hidroh.materialistic.widget.StoryRecyclerViewAdapter;
public class ListFragment extends BaseListFragment {
public static final String EXTRA_ITEM_MANAGER = ListFragment.class.getName() + ".EXTRA_ITEM_MANAGER";
public static final String EXTRA_FILTER = ListFragment.class.getName() + ".EXTRA_FILTER";
private static final String STATE_FILTER = "state:filter";
private static final String STATE_CACHE_MODE = "state:cacheMode";
private final Preferences.Observable mPreferenceObservable = new Preferences.Observable();
private final StoryRecyclerViewAdapter mAdapter = new StoryRecyclerViewAdapter();
private SwipeRefreshLayout mSwipeRefreshLayout;
@Inject @Named(ActivityModule.HN) ItemManager mHnItemManager;
@Inject @Named(ActivityModule.ALGOLIA) ItemManager mAlgoliaItemManager;
@Inject @Named(ActivityModule.POPULAR) ItemManager mPopularItemManager;
private ItemManager mItemManager;
private View mErrorView;
private View mEmptyView;
private RefreshCallback mRefreshCallback;
private String mFilter;
private int mCacheMode = ItemManager.MODE_DEFAULT;
public interface RefreshCallback {
void onRefreshed();
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof RefreshCallback) {
mRefreshCallback = (RefreshCallback) context;
}
mPreferenceObservable.subscribe(context, this::onPreferenceChanged,
R.string.pref_highlight_updated,
R.string.pref_username,
R.string.pref_auto_viewed);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
mFilter = savedInstanceState.getString(STATE_FILTER);
mCacheMode = savedInstanceState.getInt(STATE_CACHE_MODE);
} else {
mFilter = getArguments().getString(EXTRA_FILTER);
}
mAdapter.initDisplayOptions(getActivity());
mAdapter.setCacheMode(mCacheMode);
}
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_list, container, false);
mErrorView = view.findViewById(R.id.empty);
mEmptyView = view.findViewById(R.id.empty_search);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_layout);
mSwipeRefreshLayout.setColorSchemeResources(R.color.white);
mSwipeRefreshLayout.setProgressBackgroundColorSchemeResource(
AppUtils.getThemedResId(getActivity(), R.attr.colorAccent));
if (savedInstanceState == null) {
mSwipeRefreshLayout.setRefreshing(true);
}
mSwipeRefreshLayout.setOnRefreshListener(() -> {
mCacheMode = ItemManager.MODE_NETWORK;
mAdapter.setCacheMode(mCacheMode);
refresh();
});
return view;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
String managerClassName = getArguments().getString(EXTRA_ITEM_MANAGER);
if (TextUtils.equals(managerClassName, AlgoliaClient.class.getName())) {
mItemManager = mAlgoliaItemManager;
} else if (TextUtils.equals(managerClassName, AlgoliaPopularClient.class.getName())) {
mItemManager = mPopularItemManager;
} else {
mItemManager = mHnItemManager;
}
mAdapter.setHotThresHold(AppUtils.HOT_THRESHOLD_NORMAL);
if (mItemManager == mHnItemManager && mFilter != null) {
switch (mFilter) {
case ItemManager.BEST_FETCH_MODE:
mAdapter.setHotThresHold(AppUtils.HOT_THRESHOLD_HIGH);
break;
case ItemManager.NEW_FETCH_MODE:
mAdapter.setHotThresHold(AppUtils.HOT_THRESHOLD_LOW);
break;
}
} else if (mItemManager == mPopularItemManager) {
mAdapter.setHotThresHold(AppUtils.HOT_THRESHOLD_HIGH);
}
if (mAdapter.getItems() != null) {
mAdapter.notifyDataSetChanged();
} else {
refresh();
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(STATE_FILTER, mFilter);
outState.putInt(STATE_CACHE_MODE, mCacheMode);
}
@Override
public void onDetach() {
mPreferenceObservable.unsubscribe(getActivity());
mRefreshCallback = null;
super.onDetach();
}
public void filter(String filter) {
mFilter = filter;
mAdapter.setHighlightUpdated(false);
mSwipeRefreshLayout.setRefreshing(true);
refresh();
}
@Override
protected ListRecyclerViewAdapter getAdapter() {
return mAdapter;
}
private void onPreferenceChanged(int key, boolean contextChanged) {
if (!contextChanged) {
mAdapter.initDisplayOptions(getActivity());
}
}
private void refresh() {
mAdapter.setShowAll(true);
mItemManager.getStories(mFilter, mCacheMode, new ListResponseListener(this));
}
@Synthetic
void onItemsLoaded(Item[] items) {
if (!isAttached()) {
return;
}
if (items == null) {
mSwipeRefreshLayout.setRefreshing(false);
if (mAdapter.getItems() == null || mAdapter.getItems().isEmpty()) {
// TODO make refreshing indicator visible in error view
mEmptyView.setVisibility(View.GONE);
mRecyclerView.setVisibility(View.INVISIBLE);
mErrorView.setVisibility(View.VISIBLE);
} else {
Toast.makeText(getActivity(), getString(R.string.connection_error),
Toast.LENGTH_SHORT).show();
}
} else {
mAdapter.setItems(new ArrayList<>(Arrays.asList(items)));
if (items.length == 0) {
mEmptyView.setVisibility(View.VISIBLE);
mRecyclerView.setVisibility(View.INVISIBLE);
} else {
mEmptyView.setVisibility(View.GONE);
mRecyclerView.setVisibility(View.VISIBLE);
}
mErrorView.setVisibility(View.GONE);
mSwipeRefreshLayout.setRefreshing(false);
if (mRefreshCallback != null) {
mRefreshCallback.onRefreshed();
}
}
}
static class ListResponseListener implements ResponseListener<Item[]> {
private final WeakReference<ListFragment> mListFragment;
@Synthetic
ListResponseListener(ListFragment listFragment) {
mListFragment = new WeakReference<>(listFragment);
}
@Override
public void onResponse(@Nullable final Item[] response) {
if (mListFragment.get() != null && mListFragment.get().isAttached()) {
mListFragment.get().onItemsLoaded(response);
}
}
@Override
public void onError(String errorMessage) {
if (mListFragment.get() != null && mListFragment.get().isAttached()) {
mListFragment.get().onItemsLoaded(null);
}
}
}
}