package info.justaway.fragment;
import android.app.Dialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.util.LongSparseArray;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AbsListView;
import android.widget.ListView;
import com.google.common.primitives.Longs;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import de.greenrobot.event.EventBus;
import info.justaway.R;
import info.justaway.adapter.TwitterAdapter;
import info.justaway.event.action.StatusActionEvent;
import info.justaway.event.model.StreamingDestroyStatusEvent;
import info.justaway.listener.HeaderStatusClickListener;
import info.justaway.listener.HeaderStatusLongClickListener;
import info.justaway.model.Row;
import info.justaway.model.TwitterManager;
import info.justaway.settings.BasicSettings;
import twitter4j.Query;
import twitter4j.QueryResult;
import twitter4j.Status;
import twitter4j.Twitter;
/**
* 会話を表示
*
* @author aska
*/
public class TalkFragment extends DialogFragment {
private Twitter mTwitter;
private TwitterAdapter mAdapter;
private ListView mListView;
private View mHeaderView;
private View mFooterView;
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
FragmentActivity activity = getActivity();
Dialog dialog = new Dialog(activity);
dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
dialog.setContentView(R.layout.list_talk);
final Status status = (Status) getArguments().getSerializable("status");
if (status == null) {
return dialog;
}
mListView = (ListView) dialog.findViewById(R.id.list);
mHeaderView = new View(activity);
mFooterView = new View(activity);
DisplayMetrics metrics = getResources().getDisplayMetrics();
int inReplyToAreaPixels = status.getInReplyToStatusId() > 0 ? metrics.heightPixels : 0;
if (BasicSettings.getTalkOrderNewest()) {
mHeaderView.setLayoutParams(new AbsListView.LayoutParams(
AbsListView.LayoutParams.MATCH_PARENT, 100));
mFooterView.setLayoutParams(new AbsListView.LayoutParams(
AbsListView.LayoutParams.MATCH_PARENT, inReplyToAreaPixels));
} else {
mHeaderView.setLayoutParams(new AbsListView.LayoutParams(
AbsListView.LayoutParams.MATCH_PARENT, inReplyToAreaPixels));
mFooterView.setLayoutParams(new AbsListView.LayoutParams(
AbsListView.LayoutParams.MATCH_PARENT, 100));
}
mListView.addHeaderView(mHeaderView, null, false);
mListView.addFooterView(mFooterView, null, false);
// Status(ツイート)をViewに描写するアダプター
mAdapter = new TwitterAdapter(activity, R.layout.row_tweet);
mListView.setAdapter(mAdapter);
mListView.setOnScrollListener(mOnScrollListener);
// タップ操作の登録など
mListView.setOnItemClickListener(new HeaderStatusClickListener(activity));
mListView.setOnItemLongClickListener(new HeaderStatusLongClickListener(getActivity()));
mTwitter = TwitterManager.getTwitter();
mAdapter.add(Row.newStatus(status));
if (!BasicSettings.getTalkOrderNewest()) {
mListView.setSelectionFromTop(1, 0);
}
if (status.getInReplyToStatusId() > 0) {
new LoadTalk().execute(status.getInReplyToStatusId());
} else {
if (BasicSettings.getTalkOrderNewest()) {
dialog.findViewById(R.id.guruguru_footer).setVisibility(View.GONE);
} else {
dialog.findViewById(R.id.guruguru_header).setVisibility(View.GONE);
}
}
new LoadTalkReply().execute(status);
return dialog;
}
@Override
public void onResume() {
super.onResume();
EventBus.getDefault().register(this);
}
@Override
public void onPause() {
EventBus.getDefault().unregister(this);
super.onPause();
}
@SuppressWarnings("UnusedDeclaration")
public void onEventMainThread(StatusActionEvent event) {
mAdapter.notifyDataSetChanged();
}
@SuppressWarnings("UnusedDeclaration")
public void onEventMainThread(StreamingDestroyStatusEvent event) {
mAdapter.removeStatus(event.getStatusId());
}
private AbsListView.OnScrollListener mOnScrollListener = new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
switch (scrollState) {
case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
int f = mListView.getFirstVisiblePosition();
int l = mListView.getLastVisiblePosition();
int c = mAdapter.getCount();
if (f > 0) {
mHeaderView.setLayoutParams(new AbsListView.LayoutParams(
AbsListView.LayoutParams.MATCH_PARENT, 0));
}
if (l <= c) {
mFooterView.setLayoutParams(new AbsListView.LayoutParams(
AbsListView.LayoutParams.MATCH_PARENT, 0));
}
break;
default:
break;
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
};
private class LoadTalk extends AsyncTask<Long, Void, twitter4j.Status> {
public LoadTalk() {
super();
}
@Override
protected twitter4j.Status doInBackground(Long... params) {
try {
return mTwitter.showStatus(params[0]);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
@Override
protected void onPostExecute(twitter4j.Status status) {
Dialog dialog = getDialog();
if (dialog == null) {
return;
}
if (status != null) {
if (BasicSettings.getTalkOrderNewest()) {
mAdapter.add(Row.newStatus(status));
} else {
// 表示している要素の位置
int position = mListView.getLastVisiblePosition();
// 縦スクロール位置
View view = mListView.getChildAt(position);
int y = view != null ? view.getTop() : 0;
mAdapter.insert(Row.newStatus(status), 0);
mListView.setSelectionFromTop(position + 1, y);
if (mListView.getFirstVisiblePosition() > 0) {
mHeaderView.setLayoutParams(new AbsListView.LayoutParams(
AbsListView.LayoutParams.MATCH_PARENT, 0));
}
}
Long inReplyToStatusId = status.getInReplyToStatusId();
if (inReplyToStatusId > 0) {
new LoadTalk().execute(inReplyToStatusId);
} else {
if (BasicSettings.getTalkOrderNewest()) {
dialog.findViewById(R.id.guruguru_footer).setVisibility(View.GONE);
} else {
dialog.findViewById(R.id.guruguru_header).setVisibility(View.GONE);
}
}
} else {
if (BasicSettings.getTalkOrderNewest()) {
dialog.findViewById(R.id.guruguru_footer).setVisibility(View.GONE);
} else {
dialog.findViewById(R.id.guruguru_header).setVisibility(View.GONE);
}
}
}
}
private class LoadTalkReply extends AsyncTask<twitter4j.Status, Void, ArrayList<twitter4j.Status>> {
public LoadTalkReply() {
super();
}
@Override
protected ArrayList<twitter4j.Status> doInBackground(twitter4j.Status... params) {
try {
final twitter4j.Status sourceStatus = params[0];
final Query toQuery = new Query("to:" + sourceStatus.getUser().getScreenName() + " AND filter:replies");
toQuery.setCount(200);
toQuery.setSinceId(sourceStatus.getId());
toQuery.setResultType(Query.ResultType.recent);
final QueryResult toResult = mTwitter.search(toQuery);
final List<twitter4j.Status> searchStatuses = toResult.getTweets();
if (toResult.hasNext()) {
final QueryResult nextResult = mTwitter.search(toResult.nextQuery());
searchStatuses.addAll(nextResult.getTweets());
}
final Query fromQuery = new Query("from:" + sourceStatus.getUser().getScreenName() + " AND filter:replies");
fromQuery.setCount(200);
fromQuery.setSinceId(sourceStatus.getId());
fromQuery.setResultType(Query.ResultType.recent);
final QueryResult fromResult = mTwitter.search(fromQuery);
searchStatuses.addAll(fromResult.getTweets());
LongSparseArray<Boolean> isLoadMap = new LongSparseArray<>();
for (final twitter4j.Status status : searchStatuses) {
isLoadMap.put(status.getId(), true);
}
ArrayList<twitter4j.Status> lookupStatuses = new ArrayList<>();
final ArrayList<Long> statusIds = new ArrayList<>();
for (final twitter4j.Status status : searchStatuses) {
if (status.getInReplyToStatusId() > 0 && !isLoadMap.get(status.getInReplyToStatusId(), false)) {
statusIds.add(status.getInReplyToStatusId());
isLoadMap.put(status.getInReplyToStatusId(), true);
if (statusIds.size() == 100) {
lookupStatuses.addAll(mTwitter.lookup(Longs.toArray(statusIds)));
statusIds.clear();
}
}
}
if (statusIds.size() > 0) {
lookupStatuses.addAll(mTwitter.lookup(Longs.toArray(statusIds)));
}
searchStatuses.addAll(lookupStatuses);
Collections.sort(searchStatuses, new Comparator<twitter4j.Status>() {
@Override
public int compare(twitter4j.Status arg0, twitter4j.Status arg1) {
if (arg0.getId() > arg1.getId()) {
return 1;
} else if (arg0.getId() == arg1.getId()) {
return 0;
} else {
return -1;
}
}
});
LongSparseArray<Boolean> isReplyMap = new LongSparseArray<>();
isReplyMap.put(sourceStatus.getId(), true);
ArrayList<twitter4j.Status> statuses = new ArrayList<>();
for (final twitter4j.Status status : searchStatuses) {
if (isReplyMap.get(status.getInReplyToStatusId(), false)) {
statuses.add(status);
isReplyMap.put(status.getId(), true);
}
}
return statuses;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
@Override
protected void onPostExecute(ArrayList<twitter4j.Status> statuses) {
Dialog dialog = getDialog();
if (dialog == null) {
return;
}
if (BasicSettings.getTalkOrderNewest()) {
dialog.findViewById(R.id.guruguru_header).setVisibility(View.GONE);
} else {
dialog.findViewById(R.id.guruguru_footer).setVisibility(View.GONE);
}
if (statuses == null || statuses.size() == 0) {
return;
}
if (BasicSettings.getTalkOrderNewest()) {
// 表示している要素の位置
int position = mListView.getLastVisiblePosition();
// 縦スクロール位置
View view = mListView.getChildAt(position);
int y = view != null ? view.getTop() : 0;
for (final twitter4j.Status status : statuses) {
mAdapter.insert(Row.newStatus(status), 0);
}
mListView.setSelectionFromTop(position + statuses.size(), y);
if (mListView.getFirstVisiblePosition() > 0) {
mHeaderView.setLayoutParams(new AbsListView.LayoutParams(
AbsListView.LayoutParams.MATCH_PARENT, 0));
}
} else {
for (final twitter4j.Status status : statuses) {
mAdapter.add(Row.newStatus(status));
}
}
}
}
}