package com.abewy.android.apps.klyph.fragment;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import android.app.ActionBar.OnNavigationListener;
import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
import com.abewy.android.apps.klyph.Klyph;
import com.abewy.android.apps.klyph.KlyphBundleExtras;
import com.abewy.android.apps.klyph.KlyphData;
import com.abewy.android.apps.klyph.KlyphPreferences;
import com.abewy.android.apps.klyph.R;
import com.abewy.android.apps.klyph.adapter.MultiObjectAdapter;
import com.abewy.android.apps.klyph.adapter.animation.GoogleCardStyleAdapter;
import com.abewy.android.apps.klyph.adapter.animation.KlyphAnimationAdapter;
import com.abewy.android.apps.klyph.app.IActionbarSpinner;
import com.abewy.android.apps.klyph.app.PostActivity;
import com.abewy.android.apps.klyph.core.KlyphSession;
import com.abewy.android.apps.klyph.core.fql.FriendList;
import com.abewy.android.apps.klyph.core.fql.Stream;
import com.abewy.android.apps.klyph.core.fql.serializer.StreamDeserializer;
import com.abewy.android.apps.klyph.core.fql.serializer.StreamSerializer;
import com.abewy.android.apps.klyph.core.graph.GraphObject;
import com.abewy.android.apps.klyph.core.request.BaseAsyncRequest.Callback;
import com.abewy.android.apps.klyph.core.request.RequestError;
import com.abewy.android.apps.klyph.core.request.Response;
import com.abewy.android.apps.klyph.core.util.AttrUtil;
import com.abewy.android.apps.klyph.request.AsyncRequest;
import com.abewy.android.apps.klyph.request.AsyncRequest.Query;
public class StreamListFragment extends KlyphFragment implements OnNavigationListener
{
private static final int POST_CODE = 101;
private static final int STREAM_CODE = 102;
private static String stream_position_id;
private boolean isFirstLoad = true;
private boolean isStoredData = false;
private ReadDataTask readTask;
private int spinnerPosition = 0;
private List<GraphObject> friendLists;
private boolean canSaveStream = true;
public StreamListFragment()
{
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
int query = KlyphPreferences.isAlternativeNewsfeed() ? Query.ALTERNATIVE_NEWSFEED : Query.NEWSFEED;
setRequestType(query);
setNewestRequestType(query);
setShouldLoadOnResume(false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
MultiObjectAdapter adapter = /* KlyphPreferences.areBannerAdsEnabled() ? new NewsfeedAdapter(getListView()) : */new MultiObjectAdapter(
getListView());
if (KlyphPreferences.animateCards())
{
GoogleCardStyleAdapter gcsAdapter = new GoogleCardStyleAdapter(adapter);
gcsAdapter.setAbsListView(getListView());
setListAdapter(gcsAdapter);
}
else
{
setListAdapter(adapter);
}
defineEmptyText(R.string.empty_list_no_stream);
// getListView().setPadding(0, 8, 0, 0);
// getListView().setDivider(getResources().getDrawable(R.drawable.hdivider_transparent));
// getGridView().setVerticalSpacing(16);
// getListView().setItemsCanFocus(false);
getListView().setDrawSelectorOnTop(true);
getListView().setSelector(AttrUtil.getResourceId(getActivity(), R.attr.streamSelector));
setListVisible(false);
if (KlyphData.getFriendLists() == null)
{
new AsyncRequest(Query.FRIEND_LISTS, "", "", new Callback() {
@Override
public void onComplete(Response response)
{
onRequestComplete(response);
}
}).execute();
}
super.onViewCreated(view, savedInstanceState);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK && requestCode == POST_CODE)
{
if (isNewestLoading() == false)
{
setPullToRefreshRefreshing(true);
loadNewest();
}
}
else if (resultCode == Activity.RESULT_OK && requestCode == STREAM_CODE)
{
if (data != null)
{
boolean deleted = data.getBooleanExtra(KlyphBundleExtras.DELETED, false);
if (deleted == true)
{
String id = data.getStringExtra(KlyphBundleExtras.STREAM_ID);
for (GraphObject stream : getAdapter().getItems())
{
if (((Stream) stream).getPost_id().equals(id))
{
// delete(stream);
stream.setToDelete(true);
getAdapter().remove(stream, true);
storeSessionStreams();
break;
}
}
}
}
}
}
@Override
protected int getCustomLayout()
{
return R.layout.list_timeline;
}
@Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
}
@Override
public void load()
{
if (isFirstLoad)
{
if (KlyphData.getLastStreams() != null)
{
populate(KlyphData.getLastStreams());
if (stream_position_id != null)
{
for (GraphObject graphObject : getAdapter().getItems())
{
if (graphObject instanceof Stream && stream_position_id.equals(((Stream) graphObject).getPost_id()))
{
getListView().setSelection(getAdapter().getItemPosition(graphObject));
}
}
}
setNoMoreData(false);
}
else
{
readTask = new ReadDataTask();
readTask.execute();
}
}
else
{
super.load();
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
{
menu.add(Menu.NONE, R.id.menu_post, Menu.NONE, "Post").setIcon(AttrUtil.getResourceId(getActivity(), R.attr.editIcon))
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
if (item.getItemId() == R.id.menu_post)
{
if (getActivity() != null)
startActivityForResult(new Intent(getActivity(), PostActivity.class), POST_CODE);
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void populate(List<GraphObject> data)
{
Log.d("StreamListFragment", "populate: ");
int previousSize = getAdapter().getCount();
super.populate(data);
if (data.size() > 0)
{
setOffset(((Stream) data.get(data.size() - 1)).getCreated_time());
if (canSaveStream)
{
storeSessionStreams();
if (previousSize < 15 && !isStoredData)
storeData();
}
}
// getListView().setItemsCanFocus(false);
isFirstLoad = false;
}
@Override
protected void populateNewest(List<GraphObject> data)
{
int n = data.size();
if (n > 0)
{
int index = getListView().getFirstVisiblePosition();
View v = getListView().getChildAt(index);
int top = v == null ? 0 : v.getTop();
int lastIndex = -1;
if (KlyphPreferences.getNewsfeedGoToTop() == false)
{
List<GraphObject> list = new ArrayList<GraphObject>();
list.addAll(getAdapter().getItems());
// Looking for a matching post
outer: for (int i = 0; i < n; i++)
{
Stream stream = (Stream) data.get(i);
for (int j = 0, m = list.size(); j < m; j++)
{
if (list.get(j) instanceof Stream)
{
Stream s = (Stream) list.get(j);
Log.d("StreamListFragment", "populateNewest: " + stream.getPost_id() + " " + s.getPost_id());
if (stream.getPost_id().equals(s.getPost_id()))
{
lastIndex = i;
// list.remove(s);
// list.add(stream);
break outer;
}
}
}
}
Log.d("StreamListFragment", "populateNewest: " + lastIndex);
// If no match, then insert all the data
if (lastIndex == -1)
lastIndex = data.size();
// Insert filtered data
for (int i = lastIndex - 1; i >= 0; i--)
{
list.add(0, data.get(i));
}
getAdapter().clear(false);
getAdapter().addAll(list);
}
else
{
getAdapter().clear(false);
getAdapter().addAll(data);
setOffset(((Stream) data.get(data.size() - 1)).getCreated_time());
}
if (getListAdapter() instanceof KlyphAnimationAdapter)
{
int firstVisiblePosition = getListView().getFirstVisiblePosition();
int lastVisiblePosition = getListView().getLastVisiblePosition();
if (firstVisiblePosition != lastVisiblePosition)
((KlyphAnimationAdapter) getListAdapter()).deactivateNext(lastVisiblePosition - firstVisiblePosition);
else
((KlyphAnimationAdapter) getListAdapter()).deactivateNext(1);
}
getAdapter().notifyDataSetChanged();
if (KlyphPreferences.getNewsfeedGoToTop() == false)
{
getListView().setSelectionFromTop(lastIndex, top);
}
}
setNewestLoading(false);
setPullToRefreshRefreshing(false);
if (data.size() > 0)
{
storeSessionStreams();
storeData();
}
}
private void storeSessionStreams()
{
if (getAdapter() != null && getAdapter().getCount() > 0)
{
// Make a copy of the list
List<GraphObject> streams = new ArrayList<GraphObject>();
// Add only the streams (e.g. no progress or error items)
for (GraphObject graphObject : getAdapter().getItems())
{
if (graphObject instanceof Stream)
streams.add(graphObject);
}
KlyphData.setLastStreams(streams);
}
}
@Override
protected String getNewestOffset(GraphObject graphObject)
{
Stream stream = (Stream) graphObject;
return stream.getCreated_time();
}
private void storeData()
{
new StoreDataTask().execute();
}
@Override
public void onListItemClick(ListView l, View v, int position, long id)
{
GraphObject object = (GraphObject) l.getItemAtPosition(position);
if (object instanceof Stream)
{
Stream stream = (Stream) l.getItemAtPosition(position);
if (stream.isSelectable(0) == true)
{
startActivityForResult(Klyph.getIntentForGraphObject(getActivity(), stream), STREAM_CODE);
}
}
}
private class ReadDataTask extends AsyncTask<Void, Void, List<GraphObject>>
{
@Override
protected List<GraphObject> doInBackground(Void... params)
{
// long time = new Date().getTime();
String json = KlyphPreferences.getLastStories();
// Log.d("StreamListFragment", "read last stories from prefs time " + (new Date().getTime() - time));
JSONArray data;
try
{
data = new JSONArray(json);
}
catch (JSONException e)
{
return null;
}
// Log.d("StreamListFragment", "read last stories jsonarray time " + (new Date().getTime() - time));
StreamDeserializer ss = new StreamDeserializer();
List<GraphObject> list = ss.deserializeArray(data);
// Log.d("StreamListFragment", "read last stories time " + (new Date().getTime() - time));
return list;
}
@Override
protected void onPostExecute(List<GraphObject> result)
{
onStoredDataLoaded(result);
}
}
private void onStoredDataLoaded(final List<GraphObject> data)
{
if (data != null && getView() != null)
{
if (getActivity() != null)
{
getActivity().runOnUiThread(new Runnable() {
@Override
public void run()
{
isStoredData = true;
populate(data);
isStoredData = false;
setNoMoreData(false);
setPullToRefreshRefreshing(true);
loadNewest();
}
});
}
}
else
{
if (getActivity() != null)
{
getActivity().runOnUiThread(new Runnable() {
@Override
public void run()
{
StreamListFragment.super.load();
}
});
}
}
}
private class StoreDataTask extends AsyncTask<Void, Void, Void>
{
@Override
protected Void doInBackground(Void... params)
{
long time = new Date().getTime();
List<GraphObject> streams = KlyphData.getLastStreams().subList(0, Math.min(15, KlyphData.getLastStreams().size()));
StreamSerializer ss = new StreamSerializer();
JSONArray json = ss.serializeArray(streams);
String jsonString = json.toString();
KlyphPreferences.setLastStories(jsonString);
Log.d("StreamListFragment", "save last stories time " + (new Date().getTime() - time));
return null;
}
@Override
protected void onPostExecute(Void params)
{
}
}
@Override
public void onPause()
{
if (getListView() != null && getAdapter() != null)
{
int pos = getListView().getFirstVisiblePosition();
GraphObject o = getAdapter().getItem(pos);
if (pos < getAdapter().getCount() && o instanceof Stream)
{
stream_position_id = ((Stream) o).getPost_id();
}
else if (pos > 0)
{
pos--;
if (pos < getAdapter().getCount() && o instanceof Stream)
stream_position_id = ((Stream) o).getPost_id();
}
}
setPullToRefreshRefreshing(false);
super.onPause();
}
@Override
public void onDestroyView()
{
Log.d("StreamListFragment", "onDestroyView");
if (readTask != null)
{
readTask.cancel(true);
readTask = null;
}
super.onDestroyView();
}
@Override
public void onDestroy()
{
Log.d("StreamListFragment", "onDestroy");
if (readTask != null)
{
readTask.cancel(true);
readTask = null;
}
super.onDestroy();
}
// ___ Action bar spinner & friend lists
private void onRequestComplete(final Response response)
{
if (getActivity() != null)
{
getActivity().runOnUiThread(new Runnable() {
@Override
public void run()
{
if (response.getError() == null)
{
onRequestSuccess(response.getGraphObjectList());
}
else
{
onRequestError(response.getError());
}
}
});
}
}
private void onRequestSuccess(List<GraphObject> result)
{
KlyphData.setFriendLists(result);
if (getView() != null && getListView() != null)
{
onSetToFront(getActivity());
}
}
private void onRequestError(RequestError error)
{
}
@Override
public boolean onNavigationItemSelected(int itemPosition, long itemId)
{
if (spinnerPosition != itemPosition)
{
spinnerPosition = itemPosition;
cancelRequest();
if (spinnerPosition == 0)
{
int query = KlyphPreferences.isAlternativeNewsfeed() ? Query.ALTERNATIVE_NEWSFEED : Query.NEWSFEED;
setRequestType(query);
setNewestRequestType(query);
setElementId(KlyphSession.getSessionUserId());
canSaveStream = true;
}
else
{
int query = Query.FRIEND_LIST_NEWSFEED;
setRequestType(query);
setNewestRequestType(query);
FriendList fl = (FriendList) friendLists.get(itemPosition);
setElementId(fl.getFlid());
canSaveStream = false;
}
setOffset(null);
clearAndRefresh();
return true;
}
return false;
}
@Override
public void onSetToFront(Activity activity)
{
friendLists = KlyphData.getFriendLists();
if (activity != null && friendLists != null && friendLists.size() > 0)
{
FriendList fl = new FriendList();
fl.setOwner(KlyphSession.getSessionUserId());
fl.setName(activity.getString(R.string.fragment_header_newsfeed));
friendLists.add(0, fl);
((IActionbarSpinner) activity).displaySpinnerInActionBar(friendLists, spinnerPosition, this);
activity.setTitle("");
}
}
@Override
public void onSetToBack(Activity activity)
{
if (activity != null)
((IActionbarSpinner) activity).removeSpinnerInActionBar();
}
}