package org.qii.weiciyuan.ui.maintimeline;
import org.qii.weiciyuan.R;
import org.qii.weiciyuan.bean.AccountBean;
import org.qii.weiciyuan.bean.CommentBean;
import org.qii.weiciyuan.bean.CommentListBean;
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.CommentTimeLineData;
import org.qii.weiciyuan.bean.android.TimeLinePosition;
import org.qii.weiciyuan.dao.destroy.DestroyCommentDao;
import org.qii.weiciyuan.dao.unread.ClearUnreadDao;
import org.qii.weiciyuan.othercomponent.AppNotificationCenter;
import org.qii.weiciyuan.othercomponent.unreadnotification.NotificationServiceHelper;
import org.qii.weiciyuan.support.database.MentionCommentsTimeLineDBTask;
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.actionmenu.CommentFloatingMenu;
import org.qii.weiciyuan.ui.actionmenu.CommentSingleChoiceModeListener;
import org.qii.weiciyuan.ui.adapter.CommentListAdapter;
import org.qii.weiciyuan.ui.basefragment.AbstractTimeLineFragment;
import org.qii.weiciyuan.ui.interfaces.IRemoveItem;
import org.qii.weiciyuan.ui.loader.MentionsCommentDBLoader;
import org.qii.weiciyuan.ui.loader.MentionsCommentMsgLoader;
import org.qii.weiciyuan.ui.main.MainTimeLineActivity;
import org.qii.weiciyuan.ui.main.MentionsTimeLine;
import android.app.ActionBar;
import android.app.NotificationManager;
import android.content.Context;
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.AbsListView;
import android.widget.AdapterView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
/**
* User: qii
* Date: 13-1-23
*/
public class MentionsCommentTimeLineFragment extends AbstractTimeLineFragment<CommentListBean>
implements IRemoveItem {
private static final String ARGUMENTS_ACCOUNT_EXTRA = MentionsCommentTimeLineFragment.class.getName() + ":account_extra";
private static final String ARGUMENTS_USER_EXTRA = MentionsCommentTimeLineFragment.class.getName() + ":userBean_extra";
private static final String ARGUMENTS_TOKEN_EXTRA = MentionsCommentTimeLineFragment.class.getName() + ":token_extra";
private static final String ARGUMENTS_DATA_EXTRA = MentionsCommentTimeLineFragment.class.getName() + ":msg_extra";
private static final String ARGUMENTS_TIMELINE_POSITION_EXTRA = MentionsCommentTimeLineFragment.class.getName()
+ ":timeline_position_extra";
private AccountBean accountBean;
private UserBean userBean;
private String token;
private RemoveTask removeTask;
private CommentListBean bean = new CommentListBean();
private TimeLinePosition timeLinePosition;
private final int POSITION_IN_PARENT_FRAGMENT = 1;
@Override
public CommentListBean getList() {
return bean;
}
public static MentionsCommentTimeLineFragment newInstance(AccountBean accountBean,
UserBean userBean,
String token) {
MentionsCommentTimeLineFragment fragment = new MentionsCommentTimeLineFragment();
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 MentionsCommentTimeLineFragment() {
}
protected void clearAndReplaceValue(CommentListBean value) {
getList().getItemList().clear();
getList().getItemList().addAll(value.getItemList());
}
@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);
}
}
@Override
protected void onListViewScrollStop() {
super.onListViewScrollStop();
timeLinePosition = Utility.getCurrentPositionFromListView(getListView());
}
@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) {
MentionCommentsTimeLineDBTask.asyncUpdatePosition(timeLinePosition,
accountBean.getUid());
}
}
private void setActionBarTabCount(int count) {
MentionsTimeLine parent = (MentionsTimeLine) getParentFragment();
ActionBar.Tab tab = parent.getCommentTab();
if (tab == null) {
return;
}
String tabTag = (String) tab.getTag();
if (MentionsCommentTimeLineFragment.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);
}
}
}
private void setLeftMenuUnreadCount(int count) {
MainTimeLineActivity mainTimeLineActivity = (MainTimeLineActivity) getActivity();
if (mainTimeLineActivity == null) {
return;
}
mainTimeLineActivity.setMentionsCommentCount(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);
CommentListBean savedBean = savedInstanceState
.getParcelable(ARGUMENTS_DATA_EXTRA);
Loader<CommentTimeLineData> loader = getLoaderManager()
.getLoader(DB_CACHE_LOADER_ID);
if (loader != null) {
getLoaderManager().initLoader(DB_CACHE_LOADER_ID, null, dbCallback);
}
if (savedBean != null && savedBean.getSize() > 0) {
clearAndReplaceValue(savedBean);
timeLineAdapter.notifyDataSetChanged();
refreshLayout(getList());
AppNotificationCenter.getInstance().addCallback(callback);
} else {
getLoaderManager().initLoader(DB_CACHE_LOADER_ID, null, dbCallback);
}
break;
}
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getListView().setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);
getListView().setOnItemLongClickListener(onItemLongClickListener);
newMsgTipBar.setType(TopTipBar.Type.ALWAYS);
}
private AdapterView.OnItemLongClickListener onItemLongClickListener
= new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
if (position - 1 < getList().getSize() && position - 1 >= 0) {
if (actionMode != null) {
actionMode.finish();
actionMode = null;
getListView().setItemChecked(position, true);
timeLineAdapter.notifyDataSetChanged();
actionMode = getActivity().startActionMode(
new CommentSingleChoiceModeListener(getListView(), timeLineAdapter,
MentionsCommentTimeLineFragment.this,
getList().getItemList().get(position - 1)));
return true;
} else {
getListView().setItemChecked(position, true);
timeLineAdapter.notifyDataSetChanged();
actionMode = getActivity().startActionMode(
new CommentSingleChoiceModeListener(getListView(), timeLineAdapter,
MentionsCommentTimeLineFragment.this,
getList().getItemList().get(position - 1)));
return true;
}
}
return false;
}
};
@Override
public void removeItem(int position) {
clearActionMode();
if (removeTask == null || removeTask.getStatus() == MyAsyncTask.Status.FINISHED) {
removeTask = new RemoveTask(GlobalContext.getInstance().getSpecialToken(),
getList().getItemList().get(position).getId(), position);
removeTask.executeOnExecutor(MyAsyncTask.THREAD_POOL_EXECUTOR);
}
}
@Override
public void removeCancel() {
clearActionMode();
}
class RemoveTask extends MyAsyncTask<Void, Void, Boolean> {
String token;
String id;
int positon;
WeiboException e;
public RemoveTask(String token, String id, int positon) {
this.token = token;
this.id = id;
this.positon = positon;
}
@Override
protected Boolean doInBackground(Void... params) {
DestroyCommentDao dao = new DestroyCommentDao(token, id);
try {
return dao.destroy();
} catch (WeiboException e) {
this.e = e;
cancel(true);
return false;
}
}
@Override
protected void onCancelled(Boolean aBoolean) {
super.onCancelled(aBoolean);
if (Utility.isAllNotNull(getActivity(), this.e)) {
Toast.makeText(getActivity(), e.getError(), Toast.LENGTH_SHORT).show();
}
}
@Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
if (aBoolean) {
((CommentListAdapter) timeLineAdapter).removeItem(positon);
}
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(false);
}
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());
}
}
@Override
protected void buildListAdapter() {
CommentListAdapter adapter = new CommentListAdapter(this,
getList().getItemList(),
getListView(), true, false);
adapter.setTopTipBar(newMsgTipBar);
timeLineAdapter = adapter;
pullToRefreshListView.setAdapter(timeLineAdapter);
}
protected void listViewItemClick(AdapterView parent, View view, int position, long id) {
CommentFloatingMenu menu = new CommentFloatingMenu(getList().getItem(position));
menu.show(getFragmentManager(), "");
}
@Override
protected void newMsgLoaderSuccessCallback(CommentListBean newValue, Bundle loaderArgs) {
if (newValue != null && newValue.getItemList().size() > 0) {
addNewDataAndRememberPosition(newValue);
}
NotificationManager notificationManager = (NotificationManager) getActivity()
.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(NotificationServiceHelper
.getMentionsCommentNotificationId(GlobalContext.getInstance().getAccountBean()));
}
private void addNewDataAndRememberPosition(final CommentListBean 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<CommentBean> unreadData = newValue.getItemList();
for (CommentBean comment : unreadData) {
if (comment != null) {
MentionsCommentTimeLineFragment.this.timeLinePosition.newMsgIds
.add(comment.getIdLong());
}
}
newMsgTipBar
.setValue(
MentionsCommentTimeLineFragment.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(
MentionsCommentTimeLineFragment.this.timeLinePosition.newMsgIds.size());
MentionCommentsTimeLineDBTask.asyncReplace(getList(), accountBean.getUid());
}
protected void middleMsgLoaderSuccessCallback(int position, CommentListBean newValue,
boolean towardsBottom) {
if (getActivity() != null && newValue != null && newValue.getSize() > 0) {
getList().addMiddleData(position, newValue, towardsBottom);
getAdapter().notifyDataSetChanged();
MentionCommentsTimeLineDBTask.asyncReplace(getList(), accountBean.getUid());
}
}
@Override
protected void oldMsgLoaderSuccessCallback(CommentListBean newValue) {
if (newValue != null && newValue.getItemList().size() > 1) {
getList().addOldData(newValue);
getAdapter().notifyDataSetChanged();
MentionCommentsTimeLineDBTask.asyncReplace(getList(), accountBean.getUid());
}
}
private LoaderManager.LoaderCallbacks<CommentTimeLineData> dbCallback
= new LoaderManager.LoaderCallbacks<CommentTimeLineData>() {
@Override
public Loader<CommentTimeLineData> onCreateLoader(int id, Bundle args) {
getPullToRefreshListView().setVisibility(View.INVISIBLE);
return new MentionsCommentDBLoader(getActivity(),
GlobalContext.getInstance().getCurrentAccountId());
}
@Override
public void onLoadFinished(Loader<CommentTimeLineData> loader, CommentTimeLineData result) {
if (result != null) {
clearAndReplaceValue(result.cmtList);
timeLinePosition = result.position;
}
getPullToRefreshListView().setVisibility(View.VISIBLE);
getAdapter().notifyDataSetChanged();
setListViewPositionFromPositionsCache();
refreshLayout(getList());
/**
* when this account first open app,if he don't have any data in database,fetch data from server automally
*/
if (getList().getSize() == 0) {
getPullToRefreshListView().setRefreshing();
loadNewMsg();
}
getLoaderManager().destroyLoader(loader.getId());
AppNotificationCenter.getInstance().addCallback(callback);
}
@Override
public void onLoaderReset(Loader<CommentTimeLineData> loader) {
}
};
protected Loader<AsyncTaskLoaderResult<CommentListBean>> 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 MentionsCommentMsgLoader(getActivity(), accountId, token, sinceId, null);
}
protected Loader<AsyncTaskLoaderResult<CommentListBean>> onCreateMiddleMsgLoader(int id,
Bundle args, String middleBeginId, String middleEndId, String middleEndTag,
int middlePosition) {
String accountId = accountBean.getUid();
String token = accountBean.getAccess_token();
return new MentionsCommentMsgLoader(getActivity(), accountId, token, middleBeginId,
middleEndId);
}
protected Loader<AsyncTaskLoaderResult<CommentListBean>> 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 MentionsCommentMsgLoader(getActivity(), accountId, token, null, maxId);
}
private AppNotificationCenter.Callback callback = new AppNotificationCenter.Callback() {
@Override
public void unreadMentionsCommentChanged(AccountBean account, CommentListBean data) {
super.unreadMentionsCommentChanged(account, data);
if (!accountBean.equals(account)) {
return;
}
addUnreadMessage(data);
clearUnreadMentions(AppNotificationCenter.getInstance().getUnreadBean(account));
}
};
private void addUnreadMessage(CommentListBean data) {
if (data != null && data.getSize() > 0) {
CommentBean last = data.getItem(data.getSize() - 1);
boolean dup = getList().getItemList().contains(last);
if (!dup) {
addNewDataAndRememberPosition(data);
}
}
}
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())
.clearMentionCommentUnread(data,
GlobalContext.getInstance().getAccountBean().getUid());
} catch (WeiboException ignored) {
}
return null;
}
}.executeOnExecutor(MyAsyncTask.THREAD_POOL_EXECUTOR);
}
}