package org.qii.weiciyuan.ui.maintimeline;
import org.qii.weiciyuan.R;
import org.qii.weiciyuan.bean.AccountBean;
import org.qii.weiciyuan.bean.MessageBean;
import org.qii.weiciyuan.bean.MessageListBean;
import org.qii.weiciyuan.bean.MessageReCmtCountBean;
import org.qii.weiciyuan.bean.UnreadBean;
import org.qii.weiciyuan.bean.UserBean;
import org.qii.weiciyuan.bean.android.AsyncTaskLoaderResult;
import org.qii.weiciyuan.bean.android.MentionTimeLineData;
import org.qii.weiciyuan.bean.android.TimeLinePosition;
import org.qii.weiciyuan.dao.maintimeline.TimeLineReCmtCountDao;
import org.qii.weiciyuan.dao.unread.ClearUnreadDao;
import org.qii.weiciyuan.othercomponent.AppNotificationCenter;
import org.qii.weiciyuan.support.database.MentionWeiboTimeLineDBTask;
import org.qii.weiciyuan.support.debug.AppLogger;
import org.qii.weiciyuan.support.error.WeiboException;
import org.qii.weiciyuan.support.lib.MyAsyncTask;
import org.qii.weiciyuan.support.lib.TopTipBar;
import org.qii.weiciyuan.support.utils.GlobalContext;
import org.qii.weiciyuan.support.utils.Utility;
import org.qii.weiciyuan.ui.adapter.StatusListAdapter;
import org.qii.weiciyuan.ui.basefragment.AbstractMessageTimeLineFragment;
import org.qii.weiciyuan.ui.browser.BrowserWeiboMsgActivity;
import org.qii.weiciyuan.ui.loader.MentionsWeiboMsgLoader;
import org.qii.weiciyuan.ui.loader.MentionsWeiboTimeDBLoader;
import org.qii.weiciyuan.ui.main.MainTimeLineActivity;
import org.qii.weiciyuan.ui.main.MentionsTimeLine;
import android.app.ActionBar;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.AdapterView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
/**
* User: qii
* Date: 12-7-29
* Weibo repost message timeline
*/
public class MentionsWeiboTimeLineFragment
extends AbstractMessageTimeLineFragment<MessageListBean> {
private static final String ARGUMENTS_ACCOUNT_EXTRA = MentionsWeiboTimeLineFragment.class.getName() + ":account_extra";
private static final String ARGUMENTS_USER_EXTRA = MentionsWeiboTimeLineFragment.class.getName() + ":userBean_extra";
private static final String ARGUMENTS_TOKEN_EXTRA = MentionsWeiboTimeLineFragment.class.getName() + ":token_extra";
private static final String ARGUMENTS_DATA_EXTRA = MentionsWeiboTimeLineFragment.class.getName() + ":msg_extra";
private static final String ARGUMENTS_TIMELINE_POSITION_EXTRA = MentionsWeiboTimeLineFragment.class.getName()
+ ":timeline_position_extra";
private AccountBean accountBean;
private UserBean userBean;
private String token;
private TimeLinePosition timeLinePosition;
private MessageListBean bean = new MessageListBean();
private final int POSITION_IN_PARENT_FRAGMENT = 0;
@Override
public MessageListBean getList() {
return bean;
}
public static MentionsWeiboTimeLineFragment newInstance(AccountBean accountBean,
UserBean userBean, String token) {
MentionsWeiboTimeLineFragment fragment = new MentionsWeiboTimeLineFragment();
Bundle bundle = new Bundle();
bundle.putParcelable(ARGUMENTS_ACCOUNT_EXTRA, accountBean);
bundle.putParcelable(ARGUMENTS_USER_EXTRA, userBean);
bundle.putString(ARGUMENTS_TOKEN_EXTRA, token);
fragment.setArguments(bundle);
return fragment;
}
public MentionsWeiboTimeLineFragment() {
}
@Override
public void onResume() {
super.onResume();
setListViewPositionFromPositionsCache();
showUIUnreadCount(newMsgTipBar.getValues().size());
newMsgTipBar.setOnChangeListener(new TopTipBar.OnChangeListener() {
@Override
public void onChange(int count) {
showUIUnreadCount(newMsgTipBar.getValues().size());
}
});
}
@Override
public void onPause() {
super.onPause();
if (!getActivity().isChangingConfigurations()) {
saveTimeLinePositionToDB();
}
}
@Override
public void onDestroy() {
super.onDestroy();
AppNotificationCenter.getInstance().removeCallback(callback);
}
private void saveTimeLinePositionToDB() {
TimeLinePosition current = Utility.getCurrentPositionFromListView(getListView());
if (!current.isEmpty()) {
timeLinePosition = current;
timeLinePosition.newMsgIds = newMsgTipBar.getValues();
}
if (timeLinePosition != null) {
MentionWeiboTimeLineDBTask.asyncUpdatePosition(timeLinePosition,
accountBean.getUid());
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
newMsgTipBar.setType(TopTipBar.Type.ALWAYS);
}
@Override
protected void onListViewScrollStop() {
super.onListViewScrollStop();
timeLinePosition = Utility.getCurrentPositionFromListView(getListView());
}
@Override
protected void buildListAdapter() {
StatusListAdapter adapter = new StatusListAdapter(this,
getList().getItemList(),
getListView(), true, false);
adapter.setTopTipBar(newMsgTipBar);
timeLineAdapter = adapter;
getListView().setAdapter(timeLineAdapter);
}
private void setActionBarTabCount(int count) {
MentionsTimeLine parent = (MentionsTimeLine) getParentFragment();
ActionBar.Tab tab = parent.getWeiboTab();
if (tab == null) {
return;
}
String tabTag = (String) tab.getTag();
if (MentionsWeiboTimeLineFragment.class.getName().equals(tabTag)) {
View customView = tab.getCustomView();
TextView countTV = (TextView) customView.findViewById(R.id.tv_home_count);
countTV.setText(String.valueOf(count));
if (count > 0) {
countTV.setVisibility(View.VISIBLE);
} else {
countTV.setVisibility(View.GONE);
}
}
}
@Override
protected void newMsgLoaderSuccessCallback(MessageListBean newValue, Bundle loaderArgs) {
if (getActivity() != null && newValue.getSize() > 0) {
addNewDataAndRememberPosition(newValue);
}
}
private void addNewDataAndRememberPosition(final MessageListBean newValue) {
AppLogger.i("Add new unread data to memory cache");
if (getActivity() == null || newValue.getSize() == 0) {
AppLogger.i("Activity is destroyed or new data count is zero, give up");
return;
}
final boolean isDataSourceEmpty = getList().getSize() == 0;
TimeLinePosition previousPosition = Utility.getCurrentPositionFromListView(getListView());
getList().addNewData(newValue);
if (isDataSourceEmpty) {
newMsgTipBar.setValue(newValue, true);
newMsgTipBar.clearAndReset();
getAdapter().notifyDataSetChanged();
AppLogger
.i("Init data source is empty, ListView jump to zero position after refresh, first time open app? ");
getListView().setSelection(0);
saveTimeLinePositionToDB();
} else {
if (previousPosition.isEmpty() && timeLinePosition != null) {
previousPosition = timeLinePosition;
}
AppLogger.i("Previous first visible item id " + previousPosition.firstItemId);
getAdapter().notifyDataSetChanged();
List<MessageBean> unreadData = newValue.getItemList();
for (MessageBean message : unreadData) {
if (message != null) {
MentionsWeiboTimeLineFragment.this.timeLinePosition.newMsgIds
.add(message.getIdLong());
}
}
newMsgTipBar
.setValue(
MentionsWeiboTimeLineFragment.this.timeLinePosition.newMsgIds);
int positionInAdapter = Utility.getAdapterPositionFromItemId(getAdapter(),
previousPosition.firstItemId);
//use 1 px to show newMsgTipBar
AppLogger.i("ListView restore to previous position " + positionInAdapter);
getListView().getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
getListView().getViewTreeObserver().removeOnGlobalLayoutListener(this);
AppLogger.i("Save ListView position to database");
saveTimeLinePositionToDB();
}
});
Utility.setListViewAdapterPosition(getListView(), positionInAdapter,
previousPosition.top - 1,
null);
}
showUIUnreadCount(
MentionsWeiboTimeLineFragment.this.timeLinePosition.newMsgIds.size());
MentionWeiboTimeLineDBTask.asyncReplace(getList(), accountBean.getUid());
}
protected void middleMsgLoaderSuccessCallback(int position, MessageListBean newValue,
boolean towardsBottom) {
if (getActivity() != null && newValue != null && newValue.getSize() > 0) {
getList().addMiddleData(position, newValue, towardsBottom);
getAdapter().notifyDataSetChanged();
MentionWeiboTimeLineDBTask.asyncReplace(getList(), accountBean.getUid());
}
}
@Override
protected void oldMsgLoaderSuccessCallback(MessageListBean newValue) {
if (newValue != null && newValue.getSize() > 1) {
getList().addOldData(newValue);
MentionWeiboTimeLineDBTask.asyncReplace(getList(), accountBean.getUid());
} else {
Toast.makeText(getActivity(), getString(R.string.older_message_empty),
Toast.LENGTH_SHORT).show();
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (getActivity().isChangingConfigurations()) {
outState.putParcelable(ARGUMENTS_DATA_EXTRA, bean);
outState.putSerializable(ARGUMENTS_TIMELINE_POSITION_EXTRA, timeLinePosition);
}
}
private void setLeftMenuUnreadCount(int count) {
MainTimeLineActivity mainTimeLineActivity = (MainTimeLineActivity) getActivity();
if (mainTimeLineActivity == null) {
return;
}
mainTimeLineActivity.setMentionsWeiboCount(count);
}
private void showUIUnreadCount(int count) {
setActionBarTabCount(count);
setLeftMenuUnreadCount(count);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
userBean = getArguments().getParcelable(ARGUMENTS_USER_EXTRA);
accountBean = getArguments().getParcelable(ARGUMENTS_ACCOUNT_EXTRA);
token = getArguments().getString(ARGUMENTS_TOKEN_EXTRA);
super.onActivityCreated(savedInstanceState);
switch (getCurrentState(savedInstanceState)) {
case FIRST_TIME_START:
getLoaderManager().initLoader(DB_CACHE_LOADER_ID, null, dbCallback);
break;
case ACTIVITY_DESTROY_AND_CREATE:
timeLinePosition = (TimeLinePosition) savedInstanceState
.getSerializable(ARGUMENTS_TIMELINE_POSITION_EXTRA);
Loader<MentionTimeLineData> loader = getLoaderManager()
.getLoader(DB_CACHE_LOADER_ID);
if (loader != null) {
getLoaderManager().initLoader(DB_CACHE_LOADER_ID, null, dbCallback);
}
MessageListBean savedBean = savedInstanceState
.getParcelable(ARGUMENTS_DATA_EXTRA);
if (savedBean != null && savedBean.getSize() > 0) {
getList().replaceData(savedBean);
timeLineAdapter.notifyDataSetChanged();
refreshLayout(getList());
AppNotificationCenter.getInstance().addCallback(callback);
} else {
getLoaderManager().initLoader(DB_CACHE_LOADER_ID, null, dbCallback);
}
break;
}
}
@Override
protected void listViewItemClick(AdapterView parent, View view, int position, long id) {
startActivityForResult(
BrowserWeiboMsgActivity.newIntent(bean.getItemList().get(position),
GlobalContext.getInstance().getSpecialToken()),
MainTimeLineActivity.REQUEST_CODE_UPDATE_MENTIONS_WEIBO_TIMELINE_COMMENT_REPOST_COUNT);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
//use Up instead of Back to reach this fragment
if (data == null) {
return;
}
final MessageBean msg = data.getParcelableExtra("msg");
if (msg != null) {
for (int i = 0; i < getList().getSize(); i++) {
if (msg.equals(getList().getItem(i))) {
MessageBean ori = getList().getItem(i);
if (ori.getComments_count() != msg.getComments_count()
|| ori.getReposts_count() != msg.getReposts_count()) {
ori.setReposts_count(msg.getReposts_count());
ori.setComments_count(msg.getComments_count());
MentionWeiboTimeLineDBTask.asyncReplace(getList(), accountBean.getUid());
getAdapter().notifyDataSetChanged();
}
break;
}
}
}
}
private void setListViewPositionFromPositionsCache() {
Utility.setListViewAdapterPosition(getListView(),
timeLinePosition != null ? timeLinePosition.getPosition(bean) : 0,
timeLinePosition != null ? timeLinePosition.top : 0, new Runnable() {
@Override
public void run() {
setListViewUnreadTipBar(timeLinePosition);
}
});
}
private void setListViewUnreadTipBar(TimeLinePosition p) {
if (p != null && p.newMsgIds != null) {
newMsgTipBar.setValue(p.newMsgIds);
showUIUnreadCount(newMsgTipBar.getValues().size());
}
}
private LoaderManager.LoaderCallbacks<MentionTimeLineData> dbCallback
= new LoaderManager.LoaderCallbacks<MentionTimeLineData>() {
@Override
public Loader<MentionTimeLineData> onCreateLoader(int id, Bundle args) {
getPullToRefreshListView().setVisibility(View.INVISIBLE);
return new MentionsWeiboTimeDBLoader(getActivity(),
GlobalContext.getInstance().getCurrentAccountId());
}
@Override
public void onLoadFinished(Loader<MentionTimeLineData> loader, MentionTimeLineData result) {
getPullToRefreshListView().setVisibility(View.VISIBLE);
if (result != null) {
getList().replaceData(result.msgList);
timeLinePosition = result.position;
}
getAdapter().notifyDataSetChanged();
setListViewPositionFromPositionsCache();
refreshLayout(bean);
/**
* when this account first open app,if he don't have any data in database,fetch data from server automally
*/
if (bean.getSize() == 0) {
pullToRefreshListView.setRefreshing();
loadNewMsg();
} else {
new RefreshReCmtCountTask().executeOnExecutor(MyAsyncTask.THREAD_POOL_EXECUTOR);
}
getLoaderManager().destroyLoader(loader.getId());
AppNotificationCenter.getInstance().addCallback(callback);
}
@Override
public void onLoaderReset(Loader<MentionTimeLineData> loader) {
}
};
protected Loader<AsyncTaskLoaderResult<MessageListBean>> onCreateNewMsgLoader(int id,
Bundle args) {
String accountId = accountBean.getUid();
String token = accountBean.getAccess_token();
String sinceId = null;
if (getList().getItemList().size() > 0) {
sinceId = getList().getItemList().get(0).getId();
}
return new MentionsWeiboMsgLoader(getActivity(), accountId, token, sinceId, null);
}
protected Loader<AsyncTaskLoaderResult<MessageListBean>> onCreateMiddleMsgLoader(int id,
Bundle args, String middleBeginId, String middleEndId, String middleEndTag,
int middlePosition) {
String accountId = accountBean.getUid();
String token = accountBean.getAccess_token();
return new MentionsWeiboMsgLoader(getActivity(), accountId, token, middleBeginId,
middleEndId);
}
protected Loader<AsyncTaskLoaderResult<MessageListBean>> onCreateOldMsgLoader(int id,
Bundle args) {
String accountId = accountBean.getUid();
String token = accountBean.getAccess_token();
String maxId = null;
if (getList().getItemList().size() > 0) {
maxId = getList().getItemList().get(getList().getItemList().size() - 1).getId();
}
return new MentionsWeiboMsgLoader(getActivity(), accountId, token, null, maxId);
}
private AppNotificationCenter.Callback callback = new AppNotificationCenter.Callback() {
@Override
public void unreadMentionsChanged(AccountBean account, MessageListBean data) {
super.unreadMentionsChanged(account, data);
if (!accountBean.equals(account)) {
return;
}
addUnreadMessage(data);
clearUnreadMentions(AppNotificationCenter.getInstance().getUnreadBean(account));
}
};
private void addUnreadMessage(MessageListBean data) {
if (data != null && data.getSize() > 0) {
MessageBean last = data.getItem(data.getSize() - 1);
boolean dup = getList().getItemList().contains(last);
if (!dup) {
addNewDataAndRememberPosition(data);
}
}
}
private class RefreshReCmtCountTask
extends MyAsyncTask<Void, List<MessageReCmtCountBean>, List<MessageReCmtCountBean>> {
List<String> msgIds;
@Override
protected void onPreExecute() {
super.onPreExecute();
msgIds = new ArrayList<String>();
List<MessageBean> msgList = getList().getItemList();
for (MessageBean msg : msgList) {
if (msg != null) {
msgIds.add(msg.getId());
}
}
}
@Override
protected List<MessageReCmtCountBean> doInBackground(Void... params) {
try {
return new TimeLineReCmtCountDao(GlobalContext.getInstance().getSpecialToken(),
msgIds).get();
} catch (WeiboException e) {
cancel(true);
}
return null;
}
@Override
protected void onPostExecute(List<MessageReCmtCountBean> value) {
super.onPostExecute(value);
if (getActivity() == null || value == null) {
return;
}
for (int i = 0; i < value.size(); i++) {
MessageBean msg = getList().getItem(i);
MessageReCmtCountBean count = value.get(i);
if (msg != null && msg.getId().equals(count.getId())) {
msg.setReposts_count(count.getReposts());
msg.setComments_count(count.getComments());
}
}
MentionWeiboTimeLineDBTask.asyncReplace(getList(), accountBean.getUid());
getAdapter().notifyDataSetChanged();
}
}
private void clearUnreadMentions(final UnreadBean data) {
new MyAsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
try {
new ClearUnreadDao(
GlobalContext.getInstance().getAccountBean().getAccess_token())
.clearMentionStatusUnread(data,
GlobalContext.getInstance().getAccountBean().getUid());
} catch (WeiboException ignored) {
}
return null;
}
}.executeOnExecutor(MyAsyncTask.THREAD_POOL_EXECUTOR);
}
}