2014-07-03 07:48:39 +02:00
|
|
|
/*
|
2014-12-06 15:40:22 +01:00
|
|
|
* Twidere - Twitter client for Android
|
|
|
|
*
|
2014-07-03 07:48:39 +02:00
|
|
|
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
2014-12-06 15:40:22 +01:00
|
|
|
*
|
2014-07-03 07:48:39 +02:00
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
2014-12-06 15:40:22 +01:00
|
|
|
*
|
2014-07-03 07:48:39 +02:00
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
2014-12-06 15:40:22 +01:00
|
|
|
*
|
2014-07-03 07:48:39 +02:00
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package org.mariotaku.twidere.fragment.support;
|
|
|
|
|
2014-12-08 16:16:33 +01:00
|
|
|
import android.app.Activity;
|
2014-12-07 16:13:07 +01:00
|
|
|
import android.content.ActivityNotFoundException;
|
2014-07-03 07:48:39 +02:00
|
|
|
import android.content.Context;
|
2014-12-07 16:13:07 +01:00
|
|
|
import android.content.Intent;
|
2014-07-03 07:48:39 +02:00
|
|
|
import android.content.SharedPreferences;
|
2014-12-06 15:40:22 +01:00
|
|
|
import android.content.res.Resources;
|
2014-12-08 16:16:33 +01:00
|
|
|
import android.graphics.Color;
|
2015-01-03 16:16:50 +01:00
|
|
|
import android.graphics.Point;
|
2014-12-06 15:40:22 +01:00
|
|
|
import android.graphics.Rect;
|
2015-01-08 10:13:20 +01:00
|
|
|
import android.net.Uri;
|
2014-07-03 07:48:39 +02:00
|
|
|
import android.os.Bundle;
|
2014-12-06 15:40:22 +01:00
|
|
|
import android.support.annotation.Nullable;
|
2014-12-07 16:13:07 +01:00
|
|
|
import android.support.v4.app.Fragment;
|
|
|
|
import android.support.v4.app.FragmentActivity;
|
2015-01-01 11:38:34 +01:00
|
|
|
import android.support.v4.app.FragmentManager;
|
|
|
|
import android.support.v4.app.FragmentTransaction;
|
2014-07-03 07:48:39 +02:00
|
|
|
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
|
|
|
import android.support.v4.content.Loader;
|
2014-12-07 16:13:07 +01:00
|
|
|
import android.support.v4.util.Pair;
|
2015-01-17 19:58:29 +01:00
|
|
|
import android.support.v7.widget.ActionMenuView;
|
2014-12-06 15:40:22 +01:00
|
|
|
import android.support.v7.widget.CardView;
|
|
|
|
import android.support.v7.widget.LinearLayoutManager;
|
|
|
|
import android.support.v7.widget.RecyclerView;
|
|
|
|
import android.support.v7.widget.RecyclerView.Adapter;
|
|
|
|
import android.support.v7.widget.RecyclerView.LayoutParams;
|
|
|
|
import android.support.v7.widget.RecyclerView.ViewHolder;
|
2014-07-03 07:48:39 +02:00
|
|
|
import android.text.Html;
|
|
|
|
import android.text.TextUtils;
|
|
|
|
import android.text.method.LinkMovementMethod;
|
2014-12-07 16:13:07 +01:00
|
|
|
import android.util.Log;
|
2014-07-03 07:48:39 +02:00
|
|
|
import android.view.LayoutInflater;
|
2015-01-17 19:58:29 +01:00
|
|
|
import android.view.MenuInflater;
|
2014-12-07 16:13:07 +01:00
|
|
|
import android.view.MenuItem;
|
2014-07-03 07:48:39 +02:00
|
|
|
import android.view.View;
|
|
|
|
import android.view.View.OnClickListener;
|
|
|
|
import android.view.ViewGroup;
|
|
|
|
import android.widget.ImageView;
|
|
|
|
import android.widget.LinearLayout;
|
2014-12-06 15:40:22 +01:00
|
|
|
import android.widget.Space;
|
2014-07-03 07:48:39 +02:00
|
|
|
import android.widget.TextView;
|
|
|
|
|
2015-01-08 10:13:20 +01:00
|
|
|
import org.apache.http.protocol.HTTP;
|
2014-07-03 07:48:39 +02:00
|
|
|
import org.mariotaku.twidere.R;
|
2014-12-07 16:13:07 +01:00
|
|
|
import org.mariotaku.twidere.activity.support.AccountSelectorActivity;
|
|
|
|
import org.mariotaku.twidere.activity.support.ColorPickerDialogActivity;
|
2015-01-01 11:38:34 +01:00
|
|
|
import org.mariotaku.twidere.adapter.AbsStatusesAdapter.StatusAdapterListener;
|
2014-12-06 15:40:22 +01:00
|
|
|
import org.mariotaku.twidere.adapter.decorator.DividerItemDecoration;
|
|
|
|
import org.mariotaku.twidere.adapter.iface.IStatusesAdapter;
|
2014-07-03 07:48:39 +02:00
|
|
|
import org.mariotaku.twidere.app.TwidereApplication;
|
2015-01-01 11:38:34 +01:00
|
|
|
import org.mariotaku.twidere.constant.IntentConstants;
|
2015-01-06 16:46:07 +01:00
|
|
|
import org.mariotaku.twidere.loader.support.ParcelableStatusLoader;
|
2014-12-06 15:40:22 +01:00
|
|
|
import org.mariotaku.twidere.loader.support.StatusRepliesLoader;
|
|
|
|
import org.mariotaku.twidere.model.ListResponse;
|
2014-12-07 16:13:07 +01:00
|
|
|
import org.mariotaku.twidere.model.ParcelableAccount;
|
2014-12-13 16:14:47 +01:00
|
|
|
import org.mariotaku.twidere.model.ParcelableAccount.ParcelableCredentials;
|
2014-07-03 07:48:39 +02:00
|
|
|
import org.mariotaku.twidere.model.ParcelableMedia;
|
|
|
|
import org.mariotaku.twidere.model.ParcelableStatus;
|
|
|
|
import org.mariotaku.twidere.model.SingleResponse;
|
2014-12-05 14:25:27 +01:00
|
|
|
import org.mariotaku.twidere.task.TwidereAsyncTask;
|
2014-12-06 15:40:22 +01:00
|
|
|
import org.mariotaku.twidere.task.TwidereAsyncTask.Status;
|
2014-07-03 07:48:39 +02:00
|
|
|
import org.mariotaku.twidere.text.method.StatusContentMovementMethod;
|
2014-12-07 16:13:07 +01:00
|
|
|
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
|
|
|
import org.mariotaku.twidere.util.ClipboardUtils;
|
2014-12-08 16:16:33 +01:00
|
|
|
import org.mariotaku.twidere.util.CompareUtils;
|
2014-07-03 07:48:39 +02:00
|
|
|
import org.mariotaku.twidere.util.ImageLoaderWrapper;
|
2014-12-06 15:40:22 +01:00
|
|
|
import org.mariotaku.twidere.util.ImageLoadingHandler;
|
2014-07-03 07:48:39 +02:00
|
|
|
import org.mariotaku.twidere.util.OnLinkClickHandler;
|
2015-01-14 09:47:51 +01:00
|
|
|
import org.mariotaku.twidere.util.StatisticUtils;
|
2014-07-03 07:48:39 +02:00
|
|
|
import org.mariotaku.twidere.util.ThemeUtils;
|
|
|
|
import org.mariotaku.twidere.util.TwidereLinkify;
|
2015-01-03 16:16:50 +01:00
|
|
|
import org.mariotaku.twidere.util.TwitterCardUtils;
|
2014-07-03 07:48:39 +02:00
|
|
|
import org.mariotaku.twidere.util.Utils;
|
2015-01-11 10:28:45 +01:00
|
|
|
import org.mariotaku.twidere.util.Utils.OnMediaClickListener;
|
2014-12-24 05:39:21 +01:00
|
|
|
import org.mariotaku.twidere.view.ShapedImageView;
|
2014-07-03 07:48:39 +02:00
|
|
|
import org.mariotaku.twidere.view.StatusTextView;
|
2015-01-03 16:16:50 +01:00
|
|
|
import org.mariotaku.twidere.view.TwitterCardContainer;
|
2015-01-01 11:38:34 +01:00
|
|
|
import org.mariotaku.twidere.view.holder.GapViewHolder;
|
2014-12-06 15:40:22 +01:00
|
|
|
import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder;
|
|
|
|
import org.mariotaku.twidere.view.holder.StatusViewHolder;
|
2014-07-03 07:48:39 +02:00
|
|
|
|
2015-01-14 09:47:51 +01:00
|
|
|
import java.io.IOException;
|
2015-01-08 10:13:20 +01:00
|
|
|
import java.io.UnsupportedEncodingException;
|
|
|
|
import java.net.URLEncoder;
|
2014-12-06 15:40:22 +01:00
|
|
|
import java.util.ArrayList;
|
2014-07-03 07:48:39 +02:00
|
|
|
import java.util.List;
|
|
|
|
import java.util.Locale;
|
|
|
|
|
2014-07-28 12:42:48 +02:00
|
|
|
import twitter4j.TwitterException;
|
|
|
|
|
|
|
|
import static android.text.TextUtils.isEmpty;
|
2015-01-03 16:16:50 +01:00
|
|
|
import static org.mariotaku.twidere.util.UserColorNameUtils.clearUserColor;
|
|
|
|
import static org.mariotaku.twidere.util.UserColorNameUtils.clearUserNickname;
|
|
|
|
import static org.mariotaku.twidere.util.UserColorNameUtils.getUserColor;
|
|
|
|
import static org.mariotaku.twidere.util.UserColorNameUtils.getUserNickname;
|
|
|
|
import static org.mariotaku.twidere.util.UserColorNameUtils.setUserColor;
|
2014-07-28 12:42:48 +02:00
|
|
|
import static org.mariotaku.twidere.util.Utils.findStatus;
|
|
|
|
import static org.mariotaku.twidere.util.Utils.formatToLongTimeString;
|
|
|
|
import static org.mariotaku.twidere.util.Utils.getLocalizedNumber;
|
|
|
|
import static org.mariotaku.twidere.util.Utils.getUserTypeIconRes;
|
2014-12-07 16:13:07 +01:00
|
|
|
import static org.mariotaku.twidere.util.Utils.isMyRetweet;
|
2014-12-08 16:16:33 +01:00
|
|
|
import static org.mariotaku.twidere.util.Utils.openStatus;
|
2014-12-07 16:13:07 +01:00
|
|
|
import static org.mariotaku.twidere.util.Utils.openUserProfile;
|
2014-07-28 12:42:48 +02:00
|
|
|
import static org.mariotaku.twidere.util.Utils.showErrorMessage;
|
2014-12-07 16:13:07 +01:00
|
|
|
import static org.mariotaku.twidere.util.Utils.showOkMessage;
|
|
|
|
import static org.mariotaku.twidere.util.Utils.startStatusShareChooser;
|
2014-07-28 12:42:48 +02:00
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
/**
|
|
|
|
* Created by mariotaku on 14/12/5.
|
|
|
|
*/
|
|
|
|
public class StatusFragment extends BaseSupportFragment
|
2015-01-01 11:38:34 +01:00
|
|
|
implements LoaderCallbacks<SingleResponse<ParcelableStatus>>, OnMediaClickListener, StatusAdapterListener {
|
2014-07-28 12:42:48 +02:00
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
private static final int LOADER_ID_DETAIL_STATUS = 1;
|
|
|
|
private static final int LOADER_ID_STATUS_REPLIES = 2;
|
2014-12-10 13:15:09 +01:00
|
|
|
private static final int STATE_LOADED = 1;
|
|
|
|
private static final int STATE_LOADING = 2;
|
|
|
|
private static final int STATE_ERROR = 3;
|
2014-12-06 15:40:22 +01:00
|
|
|
private RecyclerView mRecyclerView;
|
|
|
|
private StatusAdapter mStatusAdapter;
|
|
|
|
private boolean mRepliesLoaderInitialized;
|
|
|
|
private LoadConversationTask mLoadConversationTask;
|
2014-12-10 13:15:09 +01:00
|
|
|
private LinearLayoutManager mLayoutManager;
|
|
|
|
private View mStatusContent;
|
|
|
|
private View mProgressContainer;
|
|
|
|
private View mErrorContainer;
|
2015-01-06 16:46:07 +01:00
|
|
|
private DividerItemDecoration mItemDecoration;
|
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
private LoaderCallbacks<List<ParcelableStatus>> mRepliesLoaderCallback = new LoaderCallbacks<List<ParcelableStatus>>() {
|
2014-07-28 12:42:48 +02:00
|
|
|
@Override
|
2014-12-06 15:40:22 +01:00
|
|
|
public Loader<List<ParcelableStatus>> onCreateLoader(int id, Bundle args) {
|
|
|
|
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
|
|
|
final String screenName = args.getString(EXTRA_SCREEN_NAME);
|
|
|
|
final long statusId = args.getLong(EXTRA_STATUS_ID, -1);
|
|
|
|
final long maxId = args.getLong(EXTRA_MAX_ID, -1);
|
|
|
|
final long sinceId = args.getLong(EXTRA_SINCE_ID, -1);
|
|
|
|
final StatusRepliesLoader loader = new StatusRepliesLoader(getActivity(), accountId,
|
2015-01-17 19:58:29 +01:00
|
|
|
screenName, statusId, maxId, sinceId, null, null, 0, true);
|
2014-12-06 15:40:22 +01:00
|
|
|
loader.setComparator(ParcelableStatus.REVERSE_ID_COMPARATOR);
|
|
|
|
return loader;
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2014-12-06 15:40:22 +01:00
|
|
|
public void onLoadFinished(Loader<List<ParcelableStatus>> loader, List<ParcelableStatus> data) {
|
|
|
|
setReplies(data);
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2014-12-06 15:40:22 +01:00
|
|
|
public void onLoaderReset(Loader<List<ParcelableStatus>> loader) {
|
2014-07-28 12:42:48 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2014-12-08 16:16:33 +01:00
|
|
|
@Override
|
|
|
|
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
|
|
|
|
switch (requestCode) {
|
|
|
|
case REQUEST_SET_COLOR: {
|
|
|
|
final ParcelableStatus status = mStatusAdapter.getStatus();
|
|
|
|
if (status == null) return;
|
|
|
|
if (resultCode == Activity.RESULT_OK) {
|
|
|
|
if (data == null) return;
|
|
|
|
final int color = data.getIntExtra(EXTRA_COLOR, Color.TRANSPARENT);
|
|
|
|
setUserColor(getActivity(), status.user_id, color);
|
|
|
|
} else if (resultCode == ColorPickerDialogActivity.RESULT_CLEARED) {
|
|
|
|
clearUserColor(getActivity(), status.user_id);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case REQUEST_SELECT_ACCOUNT: {
|
|
|
|
final ParcelableStatus status = mStatusAdapter.getStatus();
|
|
|
|
if (status == null) return;
|
|
|
|
if (resultCode == Activity.RESULT_OK) {
|
|
|
|
if (data == null || !data.hasExtra(EXTRA_ID)) return;
|
|
|
|
final long accountId = data.getLongExtra(EXTRA_ID, -1);
|
|
|
|
openStatus(getActivity(), accountId, status.id);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-07 16:13:07 +01:00
|
|
|
@Override
|
|
|
|
public View onCreateView(final LayoutInflater inflater, @Nullable final ViewGroup container,
|
|
|
|
@Nullable final Bundle savedInstanceState) {
|
|
|
|
return inflater.inflate(R.layout.fragment_status, container, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
|
|
|
super.onActivityCreated(savedInstanceState);
|
|
|
|
final View view = getView();
|
|
|
|
if (view == null) throw new AssertionError();
|
|
|
|
final Context context = view.getContext();
|
|
|
|
final boolean compact = Utils.isCompactCards(context);
|
2014-12-08 16:16:33 +01:00
|
|
|
mLayoutManager = new StatusListLinearLayoutManager(context, mRecyclerView);
|
2015-01-06 16:46:07 +01:00
|
|
|
mItemDecoration = new DividerItemDecoration(context, mLayoutManager.getOrientation());
|
2014-12-07 16:13:07 +01:00
|
|
|
if (compact) {
|
2015-01-06 16:46:07 +01:00
|
|
|
mRecyclerView.addItemDecoration(mItemDecoration);
|
2014-12-07 16:13:07 +01:00
|
|
|
}
|
|
|
|
mLayoutManager.setRecycleChildrenOnDetach(true);
|
|
|
|
mRecyclerView.setLayoutManager(mLayoutManager);
|
|
|
|
mRecyclerView.setClipToPadding(false);
|
|
|
|
mStatusAdapter = new StatusAdapter(this, compact);
|
2015-01-01 11:38:34 +01:00
|
|
|
mStatusAdapter.setEventListener(this);
|
2014-12-07 16:13:07 +01:00
|
|
|
mRecyclerView.setAdapter(mStatusAdapter);
|
|
|
|
|
2014-12-10 13:15:09 +01:00
|
|
|
setState(STATE_LOADING);
|
|
|
|
|
2014-12-07 16:13:07 +01:00
|
|
|
getLoaderManager().initLoader(LOADER_ID_DETAIL_STATUS, getArguments(), this);
|
|
|
|
}
|
|
|
|
|
2015-01-01 11:38:34 +01:00
|
|
|
@Override
|
|
|
|
public void onGapClick(GapViewHolder holder, int position) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onStatusActionClick(StatusViewHolder holder, int id, int position) {
|
|
|
|
final ParcelableStatus status = mStatusAdapter.getStatus(position);
|
|
|
|
if (status == null) return;
|
|
|
|
switch (id) {
|
|
|
|
case R.id.reply_count: {
|
|
|
|
final Context context = getActivity();
|
|
|
|
final Intent intent = new Intent(IntentConstants.INTENT_ACTION_REPLY);
|
|
|
|
intent.setPackage(context.getPackageName());
|
|
|
|
intent.putExtra(IntentConstants.EXTRA_STATUS, status);
|
|
|
|
context.startActivity(intent);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case R.id.retweet_count: {
|
|
|
|
RetweetQuoteDialogFragment.show(getFragmentManager(), status);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case R.id.favorite_count: {
|
|
|
|
final AsyncTwitterWrapper twitter = getTwitterWrapper();
|
|
|
|
if (twitter == null) return;
|
|
|
|
if (status.is_favorite) {
|
|
|
|
twitter.destroyFavoriteAsync(status.account_id, status.id);
|
|
|
|
} else {
|
|
|
|
twitter.createFavoriteAsync(status.account_id, status.id);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onStatusClick(StatusViewHolder holder, int position) {
|
|
|
|
openStatus(getActivity(), mStatusAdapter.getStatus(position), null);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2015-01-14 09:47:51 +01:00
|
|
|
public void onStatusMenuClick(StatusViewHolder holder, View itemView, int position) {
|
2015-01-17 19:58:29 +01:00
|
|
|
//TODO show status menu
|
2015-01-01 11:38:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Loader<SingleResponse<ParcelableStatus>> onCreateLoader(final int id, final Bundle args) {
|
|
|
|
final Bundle fragmentArgs = getArguments();
|
|
|
|
final long accountId = fragmentArgs.getLong(EXTRA_ACCOUNT_ID, -1);
|
|
|
|
final long statusId = fragmentArgs.getLong(EXTRA_STATUS_ID, -1);
|
|
|
|
return new ParcelableStatusLoader(getActivity(), false, fragmentArgs, accountId, statusId);
|
|
|
|
}
|
|
|
|
|
2014-12-08 16:16:33 +01:00
|
|
|
@Override
|
2014-12-10 13:15:09 +01:00
|
|
|
public void onMediaClick(View view, ParcelableMedia media, long accountId) {
|
|
|
|
Utils.openImageDirectly(getActivity(), accountId, media.url);
|
2014-12-08 16:16:33 +01:00
|
|
|
}
|
|
|
|
|
2015-01-01 11:38:34 +01:00
|
|
|
@Override
|
|
|
|
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
|
|
|
super.onViewCreated(view, savedInstanceState);
|
|
|
|
mStatusContent = view.findViewById(R.id.status_content);
|
|
|
|
mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
|
|
|
|
mProgressContainer = view.findViewById(R.id.progress_container);
|
|
|
|
mErrorContainer = view.findViewById(R.id.error_retry_container);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void fitSystemWindows(Rect insets) {
|
|
|
|
super.fitSystemWindows(insets);
|
|
|
|
// mRecyclerView.setPadding(insets.left, insets.top, insets.right, insets.bottom);
|
|
|
|
getView().setPadding(insets.left, insets.top, insets.right, insets.bottom);
|
|
|
|
}
|
|
|
|
|
2014-07-28 12:42:48 +02:00
|
|
|
@Override
|
2014-12-06 15:40:22 +01:00
|
|
|
public void onLoadFinished(final Loader<SingleResponse<ParcelableStatus>> loader,
|
|
|
|
final SingleResponse<ParcelableStatus> data) {
|
|
|
|
if (data.hasData()) {
|
2014-12-08 16:16:33 +01:00
|
|
|
final long itemId = mStatusAdapter.getItemId(mLayoutManager.findFirstVisibleItemPosition());
|
|
|
|
final View firstChild = mLayoutManager.getChildAt(0);
|
|
|
|
final int top = firstChild != null ? firstChild.getTop() : 0;
|
2014-12-06 15:40:22 +01:00
|
|
|
final ParcelableStatus status = data.getData();
|
2014-12-08 16:16:33 +01:00
|
|
|
if (mStatusAdapter.setStatus(status)) {
|
|
|
|
mLayoutManager.scrollToPositionWithOffset(1, 0);
|
|
|
|
mStatusAdapter.setConversation(null);
|
|
|
|
mStatusAdapter.setReplies(null);
|
|
|
|
loadReplies(status);
|
|
|
|
loadConversation(status);
|
|
|
|
} else {
|
|
|
|
final int position = mStatusAdapter.findPositionById(itemId);
|
|
|
|
mLayoutManager.scrollToPositionWithOffset(position, top);
|
|
|
|
}
|
2015-01-14 09:47:51 +01:00
|
|
|
try {
|
|
|
|
StatisticUtils.writeStatusOpen(status, null, 0);
|
|
|
|
} catch (IOException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
2014-12-10 13:15:09 +01:00
|
|
|
setState(STATE_LOADED);
|
2014-12-06 15:40:22 +01:00
|
|
|
} else {
|
|
|
|
//TODO show errors
|
2014-12-10 13:15:09 +01:00
|
|
|
setState(STATE_ERROR);
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-07 16:13:07 +01:00
|
|
|
private void loadConversation(ParcelableStatus status) {
|
|
|
|
if (mLoadConversationTask != null && mLoadConversationTask.getStatus() == Status.RUNNING) {
|
|
|
|
mLoadConversationTask.cancel(true);
|
|
|
|
}
|
|
|
|
mLoadConversationTask = new LoadConversationTask(this);
|
|
|
|
mLoadConversationTask.executeTask(status);
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
private void loadReplies(ParcelableStatus status) {
|
2014-07-28 12:42:48 +02:00
|
|
|
if (status == null) return;
|
2014-12-06 15:40:22 +01:00
|
|
|
final Bundle args = new Bundle();
|
|
|
|
args.putLong(EXTRA_ACCOUNT_ID, status.account_id);
|
2015-01-08 10:13:20 +01:00
|
|
|
args.putLong(EXTRA_STATUS_ID, status.retweet_id > 0 ? status.retweet_id : status.id);
|
2014-12-06 15:40:22 +01:00
|
|
|
args.putString(EXTRA_SCREEN_NAME, status.user_screen_name);
|
|
|
|
if (mRepliesLoaderInitialized) {
|
|
|
|
getLoaderManager().restartLoader(LOADER_ID_STATUS_REPLIES, args, mRepliesLoaderCallback);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
getLoaderManager().initLoader(LOADER_ID_STATUS_REPLIES, args, mRepliesLoaderCallback);
|
|
|
|
mRepliesLoaderInitialized = true;
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
|
|
|
|
2014-12-07 16:13:07 +01:00
|
|
|
private void setConversation(List<ParcelableStatus> data) {
|
|
|
|
if (mLayoutManager.getChildCount() != 0) {
|
|
|
|
final long itemId = mStatusAdapter.getItemId(mLayoutManager.findFirstVisibleItemPosition());
|
|
|
|
final int top = mLayoutManager.getChildAt(0).getTop();
|
|
|
|
mStatusAdapter.setConversation(data);
|
|
|
|
final int position = mStatusAdapter.findPositionById(itemId);
|
|
|
|
mLayoutManager.scrollToPositionWithOffset(position, top);
|
|
|
|
} else {
|
|
|
|
mStatusAdapter.setConversation(data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void setReplies(List<ParcelableStatus> data) {
|
|
|
|
if (mLayoutManager.getChildCount() != 0) {
|
|
|
|
final long itemId = mStatusAdapter.getItemId(mLayoutManager.findFirstVisibleItemPosition());
|
|
|
|
final int top = mLayoutManager.getChildAt(0).getTop();
|
|
|
|
mStatusAdapter.setReplies(data);
|
|
|
|
final int position = mStatusAdapter.findPositionById(itemId);
|
|
|
|
mLayoutManager.scrollToPositionWithOffset(position, top);
|
|
|
|
} else {
|
|
|
|
mStatusAdapter.setReplies(data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-01 11:38:34 +01:00
|
|
|
private void setState(int state) {
|
|
|
|
mStatusContent.setVisibility(state == STATE_LOADED ? View.VISIBLE : View.GONE);
|
|
|
|
mProgressContainer.setVisibility(state == STATE_LOADING ? View.VISIBLE : View.GONE);
|
|
|
|
mErrorContainer.setVisibility(state == STATE_ERROR ? View.VISIBLE : View.GONE);
|
|
|
|
}
|
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
private static class StatusAdapter extends Adapter<ViewHolder> implements IStatusesAdapter<List<ParcelableStatus>> {
|
2014-07-28 12:42:48 +02:00
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
private static final int VIEW_TYPE_DETAIL_STATUS = 0;
|
|
|
|
private static final int VIEW_TYPE_LIST_STATUS = 1;
|
|
|
|
private static final int VIEW_TYPE_CONVERSATION_LOAD_INDICATOR = 2;
|
|
|
|
private static final int VIEW_TYPE_REPLIES_LOAD_INDICATOR = 3;
|
|
|
|
private static final int VIEW_TYPE_SPACE = 4;
|
2014-07-28 12:42:48 +02:00
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
private final Context mContext;
|
2014-12-10 13:15:09 +01:00
|
|
|
private final StatusFragment mFragment;
|
2014-12-06 15:40:22 +01:00
|
|
|
private final LayoutInflater mInflater;
|
|
|
|
private final ImageLoaderWrapper mImageLoader;
|
2014-12-11 06:40:08 +01:00
|
|
|
private final ImageLoadingHandler mImageLoadingHandler;
|
2014-07-28 12:42:48 +02:00
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
private final boolean mNameFirst, mNicknameOnly;
|
|
|
|
private final int mCardLayoutResource;
|
2014-12-10 13:15:09 +01:00
|
|
|
private final int mTextSize;
|
2014-12-24 05:39:21 +01:00
|
|
|
private final int mCardBackgroundColor;
|
2015-01-04 16:12:10 +01:00
|
|
|
private final boolean mIsCompact;
|
2015-01-14 09:47:51 +01:00
|
|
|
private final int mProfileImageStyle;
|
2014-07-28 12:42:48 +02:00
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
private ParcelableStatus mStatus;
|
2014-12-13 16:14:47 +01:00
|
|
|
private ParcelableCredentials mStatusAccount;
|
2014-12-06 15:40:22 +01:00
|
|
|
private List<ParcelableStatus> mConversation, mReplies;
|
|
|
|
private boolean mDetailMediaExpanded;
|
2015-01-01 11:38:34 +01:00
|
|
|
private StatusAdapterListener mStatusAdapterListener;
|
|
|
|
private DetailStatusViewHolder mCachedHolder;
|
2014-07-28 12:42:48 +02:00
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
public StatusAdapter(StatusFragment fragment, boolean compact) {
|
|
|
|
final Context context = fragment.getActivity();
|
2014-12-10 13:15:09 +01:00
|
|
|
final Resources res = context.getResources();
|
2014-12-06 15:40:22 +01:00
|
|
|
final SharedPreferences preferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME,
|
|
|
|
Context.MODE_PRIVATE);
|
|
|
|
mFragment = fragment;
|
|
|
|
mContext = context;
|
|
|
|
mInflater = LayoutInflater.from(context);
|
|
|
|
mImageLoader = TwidereApplication.getInstance(context).getImageLoaderWrapper();
|
2014-12-11 06:40:08 +01:00
|
|
|
mImageLoadingHandler = new ImageLoadingHandler(R.id.media_preview_progress);
|
2014-12-24 05:39:21 +01:00
|
|
|
mCardBackgroundColor = ThemeUtils.getCardBackgroundColor(context);
|
2014-12-06 15:40:22 +01:00
|
|
|
mNameFirst = preferences.getBoolean(KEY_NAME_FIRST, true);
|
|
|
|
mNicknameOnly = preferences.getBoolean(KEY_NICKNAME_ONLY, true);
|
2014-12-10 13:15:09 +01:00
|
|
|
mTextSize = preferences.getInt(KEY_TEXT_SIZE, res.getInteger(R.integer.default_text_size));
|
2015-01-14 09:47:51 +01:00
|
|
|
mProfileImageStyle = Utils.getProfileImageStyle(preferences.getString(KEY_PROFILE_IMAGE_STYLE, null));
|
2015-01-04 16:12:10 +01:00
|
|
|
mIsCompact = compact;
|
2014-12-06 15:40:22 +01:00
|
|
|
if (compact) {
|
2015-01-06 16:46:07 +01:00
|
|
|
mCardLayoutResource = R.layout.card_item_status_compact;
|
2014-12-06 15:40:22 +01:00
|
|
|
} else {
|
|
|
|
mCardLayoutResource = R.layout.card_item_status;
|
|
|
|
}
|
|
|
|
}
|
2014-07-28 12:42:48 +02:00
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
public int findPositionById(long itemId) {
|
|
|
|
for (int i = 0, j = getItemCount(); i < j; i++) {
|
|
|
|
if (getItemId(i) == itemId) return i;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
2014-07-28 12:42:48 +02:00
|
|
|
|
2014-12-07 16:13:07 +01:00
|
|
|
public StatusFragment getFragment() {
|
|
|
|
return mFragment;
|
|
|
|
}
|
|
|
|
|
|
|
|
public ImageLoaderWrapper getImageLoader() {
|
|
|
|
return mImageLoader;
|
|
|
|
}
|
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
public Context getContext() {
|
|
|
|
return mContext;
|
|
|
|
}
|
2014-07-28 12:42:48 +02:00
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
@Override
|
|
|
|
public ImageLoadingHandler getImageLoadingHandler() {
|
2014-12-11 06:40:08 +01:00
|
|
|
return mImageLoadingHandler;
|
2014-12-06 15:40:22 +01:00
|
|
|
}
|
2014-07-28 12:42:48 +02:00
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
@Override
|
|
|
|
public ParcelableStatus getStatus(int position) {
|
|
|
|
final int conversationCount = getConversationCount();
|
|
|
|
if (position == getItemCount() - 1) {
|
|
|
|
return null;
|
|
|
|
} else if (position < conversationCount) {
|
|
|
|
return mConversation.get(position);
|
|
|
|
} else if (position > conversationCount) {
|
|
|
|
return mReplies.get(position - conversationCount - 1);
|
|
|
|
} else {
|
|
|
|
return mStatus;
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
@Override
|
|
|
|
public int getStatusCount() {
|
|
|
|
return getConversationCount() + 1 + getRepliesCount() + 1;
|
|
|
|
}
|
2014-07-28 12:42:48 +02:00
|
|
|
|
2015-01-10 16:17:02 +01:00
|
|
|
@Override
|
|
|
|
public long getStatusId(int position) {
|
|
|
|
final ParcelableStatus status = getStatus(position);
|
|
|
|
return status != null ? status.hashCode() : position;
|
|
|
|
}
|
|
|
|
|
2015-01-01 11:38:34 +01:00
|
|
|
@Override
|
|
|
|
public int getProfileImageStyle() {
|
2015-01-14 09:47:51 +01:00
|
|
|
return mProfileImageStyle;
|
2014-12-10 13:15:09 +01:00
|
|
|
}
|
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
@Override
|
2015-01-01 11:38:34 +01:00
|
|
|
public int getMediaPreviewStyle() {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public final void onStatusClick(StatusViewHolder holder, int position) {
|
|
|
|
if (mStatusAdapterListener != null) {
|
|
|
|
mStatusAdapterListener.onStatusClick(holder, position);
|
|
|
|
}
|
2014-12-06 15:40:22 +01:00
|
|
|
}
|
2014-07-28 12:42:48 +02:00
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
@Override
|
2014-12-07 16:13:07 +01:00
|
|
|
public void onUserProfileClick(StatusViewHolder holder, int position) {
|
2015-01-03 16:16:50 +01:00
|
|
|
final Context context = getContext();
|
|
|
|
final ParcelableStatus status = getStatus(position);
|
|
|
|
final View profileImageView = holder.getProfileImageView();
|
|
|
|
final View profileTypeView = holder.getProfileTypeView();
|
|
|
|
if (context instanceof FragmentActivity) {
|
|
|
|
final Bundle options = Utils.makeSceneTransitionOption((FragmentActivity) context,
|
|
|
|
new Pair<>(profileImageView, UserFragment.TRANSITION_NAME_PROFILE_IMAGE),
|
|
|
|
new Pair<>(profileTypeView, UserFragment.TRANSITION_NAME_PROFILE_TYPE));
|
|
|
|
Utils.openUserProfile(context, status.account_id, status.user_id, status.user_screen_name, options);
|
|
|
|
} else {
|
|
|
|
Utils.openUserProfile(context, status.account_id, status.user_id, status.user_screen_name, null);
|
|
|
|
}
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
@Override
|
2014-12-07 16:13:07 +01:00
|
|
|
public void setData(List<ParcelableStatus> data) {
|
2014-07-28 12:42:48 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2015-01-17 19:58:29 +01:00
|
|
|
@Override
|
|
|
|
public boolean shouldShowAccountsColor() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-12-12 14:53:18 +01:00
|
|
|
@Override
|
|
|
|
public AsyncTwitterWrapper getTwitterWrapper() {
|
|
|
|
return mFragment.getTwitterWrapper();
|
|
|
|
}
|
|
|
|
|
2015-01-01 11:38:34 +01:00
|
|
|
public float getTextSize() {
|
|
|
|
return mTextSize;
|
|
|
|
}
|
|
|
|
|
2014-12-08 16:16:33 +01:00
|
|
|
public ParcelableStatus getStatus() {
|
|
|
|
return mStatus;
|
|
|
|
}
|
|
|
|
|
2015-01-01 11:38:34 +01:00
|
|
|
public ParcelableCredentials getStatusAccount() {
|
|
|
|
return mStatusAccount;
|
2014-12-08 16:16:33 +01:00
|
|
|
}
|
|
|
|
|
2014-12-07 16:13:07 +01:00
|
|
|
public boolean isDetailMediaExpanded() {
|
|
|
|
return mDetailMediaExpanded;
|
2014-12-06 15:40:22 +01:00
|
|
|
}
|
2014-07-28 12:42:48 +02:00
|
|
|
|
2014-12-07 16:13:07 +01:00
|
|
|
public void setDetailMediaExpanded(boolean expanded) {
|
|
|
|
mDetailMediaExpanded = expanded;
|
|
|
|
notifyDataSetChanged();
|
2015-01-06 16:46:07 +01:00
|
|
|
updateItemDecoration();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void updateItemDecoration() {
|
|
|
|
final DividerItemDecoration decoration = mFragment.getItemDecoration();
|
|
|
|
decoration.setDecorationStart(0);
|
|
|
|
if (mReplies != null) {
|
2015-01-14 09:47:51 +01:00
|
|
|
// decoration.setDecorationEndOffset(2);
|
2015-01-06 16:46:07 +01:00
|
|
|
decoration.setDecorationEnd(getItemCount() - 2);
|
|
|
|
} else {
|
2015-01-14 09:47:51 +01:00
|
|
|
// decoration.setDecorationEndOffset(3);
|
2015-01-06 16:46:07 +01:00
|
|
|
decoration.setDecorationEnd(getItemCount() - 3);
|
|
|
|
}
|
|
|
|
mFragment.mRecyclerView.invalidateItemDecorations();
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
|
|
|
|
2015-01-06 16:46:07 +01:00
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
@Override
|
2014-12-07 16:13:07 +01:00
|
|
|
public boolean isGapItem(int position) {
|
|
|
|
return false;
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
2014-12-06 15:40:22 +01:00
|
|
|
|
|
|
|
@Override
|
2015-01-01 11:38:34 +01:00
|
|
|
public final void onGapClick(ViewHolder holder, int position) {
|
|
|
|
if (mStatusAdapterListener != null) {
|
|
|
|
mStatusAdapterListener.onGapClick((GapViewHolder) holder, position);
|
|
|
|
}
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
public boolean isNameFirst() {
|
|
|
|
return mNameFirst;
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
public boolean isNicknameOnly() {
|
|
|
|
return mNicknameOnly;
|
|
|
|
}
|
2014-07-28 12:42:48 +02:00
|
|
|
|
2015-01-01 11:38:34 +01:00
|
|
|
@Override
|
|
|
|
public void onViewDetachedFromWindow(ViewHolder holder) {
|
|
|
|
super.onViewDetachedFromWindow(holder);
|
|
|
|
if (holder instanceof DetailStatusViewHolder) {
|
|
|
|
mCachedHolder = (DetailStatusViewHolder) holder;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onViewAttachedToWindow(ViewHolder holder) {
|
|
|
|
super.onViewAttachedToWindow(holder);
|
|
|
|
if (mCachedHolder == holder) {
|
|
|
|
mCachedHolder = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-28 12:42:48 +02:00
|
|
|
@Override
|
2014-12-06 15:40:22 +01:00
|
|
|
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
|
|
|
switch (viewType) {
|
|
|
|
case VIEW_TYPE_DETAIL_STATUS: {
|
2015-01-01 11:38:34 +01:00
|
|
|
if (mCachedHolder != null) return mCachedHolder;
|
2015-01-04 16:12:10 +01:00
|
|
|
final View view;
|
|
|
|
if (mIsCompact) {
|
2015-01-06 16:46:07 +01:00
|
|
|
view = mInflater.inflate(R.layout.header_status_compact, parent, false);
|
2015-01-14 09:47:51 +01:00
|
|
|
final View cardView = view.findViewById(R.id.compact_card);
|
|
|
|
cardView.setBackgroundColor(mCardBackgroundColor);
|
2015-01-04 16:12:10 +01:00
|
|
|
} else {
|
|
|
|
view = mInflater.inflate(R.layout.header_status, parent, false);
|
2015-01-14 09:47:51 +01:00
|
|
|
final CardView cardView = (CardView) view.findViewById(R.id.card);
|
2014-12-24 05:39:21 +01:00
|
|
|
cardView.setCardBackgroundColor(mCardBackgroundColor);
|
|
|
|
}
|
2014-12-06 15:40:22 +01:00
|
|
|
return new DetailStatusViewHolder(this, view);
|
|
|
|
}
|
|
|
|
case VIEW_TYPE_LIST_STATUS: {
|
|
|
|
final View view = mInflater.inflate(mCardLayoutResource, parent, false);
|
2014-12-24 05:39:21 +01:00
|
|
|
final CardView cardView = (CardView) view.findViewById(R.id.card);
|
|
|
|
if (cardView != null) {
|
|
|
|
cardView.setCardBackgroundColor(mCardBackgroundColor);
|
|
|
|
}
|
2014-12-11 06:40:08 +01:00
|
|
|
final StatusViewHolder holder = new StatusViewHolder(this, view);
|
2015-01-04 16:12:10 +01:00
|
|
|
holder.setOnClickListeners();
|
2014-12-11 06:40:08 +01:00
|
|
|
return holder;
|
2014-12-06 15:40:22 +01:00
|
|
|
}
|
|
|
|
case VIEW_TYPE_CONVERSATION_LOAD_INDICATOR:
|
|
|
|
case VIEW_TYPE_REPLIES_LOAD_INDICATOR: {
|
|
|
|
final View view = mInflater.inflate(R.layout.card_item_load_indicator, parent,
|
|
|
|
false);
|
|
|
|
return new LoadIndicatorViewHolder(view);
|
|
|
|
}
|
|
|
|
case VIEW_TYPE_SPACE: {
|
|
|
|
return new SpaceViewHolder(new Space(mContext));
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
|
|
|
}
|
2014-12-06 15:40:22 +01:00
|
|
|
return null;
|
|
|
|
}
|
2014-07-28 12:42:48 +02:00
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
@Override
|
2014-12-07 16:13:07 +01:00
|
|
|
public void onBindViewHolder(ViewHolder holder, int position) {
|
|
|
|
switch (getItemViewType(position)) {
|
|
|
|
case VIEW_TYPE_DETAIL_STATUS: {
|
|
|
|
final ParcelableStatus status = getStatus(position);
|
|
|
|
final DetailStatusViewHolder detailHolder = (DetailStatusViewHolder) holder;
|
|
|
|
detailHolder.showStatus(status);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case VIEW_TYPE_LIST_STATUS: {
|
|
|
|
final ParcelableStatus status = getStatus(position);
|
|
|
|
final StatusViewHolder statusHolder = (StatusViewHolder) holder;
|
2015-01-14 09:47:51 +01:00
|
|
|
// Display 'in reply to' for first item
|
|
|
|
// useful to indicate whether first tweet has reply or not
|
|
|
|
statusHolder.displayStatus(status, position == 0);
|
2014-12-07 16:13:07 +01:00
|
|
|
break;
|
|
|
|
}
|
2014-12-06 15:40:22 +01:00
|
|
|
}
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2014-12-06 15:40:22 +01:00
|
|
|
public int getItemViewType(int position) {
|
|
|
|
final int conversationCount = getConversationCount();
|
|
|
|
if (position == getItemCount() - 1) {
|
|
|
|
return VIEW_TYPE_SPACE;
|
|
|
|
} else if (position < conversationCount) {
|
|
|
|
return mConversation != null ? VIEW_TYPE_LIST_STATUS : VIEW_TYPE_CONVERSATION_LOAD_INDICATOR;
|
|
|
|
} else if (position > conversationCount) {
|
|
|
|
return mReplies != null ? VIEW_TYPE_LIST_STATUS : VIEW_TYPE_REPLIES_LOAD_INDICATOR;
|
|
|
|
} else {
|
|
|
|
return VIEW_TYPE_DETAIL_STATUS;
|
|
|
|
}
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
@Override
|
2014-12-07 16:13:07 +01:00
|
|
|
public long getItemId(int position) {
|
|
|
|
final int conversationCount = getConversationCount();
|
|
|
|
if (position == getItemCount() - 1) {
|
|
|
|
return 4;
|
|
|
|
} else if (position < conversationCount) {
|
|
|
|
return mConversation != null ? mConversation.get(position).id : 2;
|
|
|
|
} else if (position > conversationCount) {
|
|
|
|
return mReplies != null ? mReplies.get(position - conversationCount - 1).id : 3;
|
|
|
|
} else {
|
|
|
|
return mStatus != null ? mStatus.id : 1;
|
2014-12-06 15:40:22 +01:00
|
|
|
}
|
|
|
|
}
|
2014-07-28 12:42:48 +02:00
|
|
|
|
2014-12-07 16:13:07 +01:00
|
|
|
@Override
|
|
|
|
public int getItemCount() {
|
|
|
|
return getStatusCount();
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
|
|
|
|
2014-12-07 16:13:07 +01:00
|
|
|
@Override
|
|
|
|
public void onItemActionClick(ViewHolder holder, int id, int position) {
|
2015-01-01 11:38:34 +01:00
|
|
|
if (mStatusAdapterListener != null) {
|
|
|
|
mStatusAdapterListener.onStatusActionClick((StatusViewHolder) holder, id, position);
|
|
|
|
}
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
|
|
|
|
2014-12-07 16:13:07 +01:00
|
|
|
@Override
|
2015-01-14 09:47:51 +01:00
|
|
|
public void onItemMenuClick(ViewHolder holder, View itemView, int position) {
|
2015-01-01 11:38:34 +01:00
|
|
|
if (mStatusAdapterListener != null) {
|
2015-01-14 09:47:51 +01:00
|
|
|
mStatusAdapterListener.onStatusMenuClick((StatusViewHolder) holder, itemView, position);
|
2015-01-01 11:38:34 +01:00
|
|
|
}
|
2014-12-06 15:40:22 +01:00
|
|
|
}
|
2014-07-28 12:42:48 +02:00
|
|
|
|
2014-12-07 16:13:07 +01:00
|
|
|
public void setConversation(List<ParcelableStatus> conversation) {
|
|
|
|
mConversation = conversation;
|
|
|
|
notifyDataSetChanged();
|
2015-01-06 16:46:07 +01:00
|
|
|
updateItemDecoration();
|
2014-12-06 15:40:22 +01:00
|
|
|
}
|
2014-07-28 12:42:48 +02:00
|
|
|
|
2015-01-01 11:38:34 +01:00
|
|
|
public void setEventListener(StatusAdapterListener listener) {
|
|
|
|
mStatusAdapterListener = listener;
|
|
|
|
}
|
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
public void setReplies(List<ParcelableStatus> replies) {
|
|
|
|
mReplies = replies;
|
|
|
|
notifyDataSetChanged();
|
2015-01-06 16:46:07 +01:00
|
|
|
updateItemDecoration();
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
|
|
|
|
2015-01-01 11:38:34 +01:00
|
|
|
public boolean setStatus(ParcelableStatus status) {
|
|
|
|
final ParcelableStatus old = mStatus;
|
|
|
|
mStatus = status;
|
|
|
|
if (status != null) {
|
|
|
|
mStatusAccount = ParcelableAccount.getCredentials(mContext, status.account_id);
|
|
|
|
} else {
|
|
|
|
mStatusAccount = null;
|
|
|
|
}
|
|
|
|
notifyDataSetChanged();
|
2015-01-06 16:46:07 +01:00
|
|
|
updateItemDecoration();
|
2015-01-01 11:38:34 +01:00
|
|
|
return !CompareUtils.objectEquals(old, status);
|
|
|
|
}
|
|
|
|
|
2014-12-07 16:13:07 +01:00
|
|
|
private int getConversationCount() {
|
|
|
|
return mConversation != null ? mConversation.size() : 1;
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
|
|
|
|
2014-12-07 16:13:07 +01:00
|
|
|
private int getRepliesCount() {
|
|
|
|
return mReplies != null ? mReplies.size() : 1;
|
|
|
|
}
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
|
|
|
|
2015-01-06 16:46:07 +01:00
|
|
|
private DividerItemDecoration getItemDecoration() {
|
|
|
|
return mItemDecoration;
|
|
|
|
}
|
|
|
|
|
2015-01-01 11:38:34 +01:00
|
|
|
@Override
|
|
|
|
public void onLoaderReset(final Loader<SingleResponse<ParcelableStatus>> loader) {
|
|
|
|
|
|
|
|
}
|
2014-12-08 16:16:33 +01:00
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
static class LoadConversationTask extends TwidereAsyncTask<ParcelableStatus, ParcelableStatus,
|
|
|
|
ListResponse<ParcelableStatus>> {
|
|
|
|
|
2014-07-28 12:42:48 +02:00
|
|
|
final Context context;
|
|
|
|
final StatusFragment fragment;
|
|
|
|
|
|
|
|
LoadConversationTask(final StatusFragment fragment) {
|
|
|
|
context = fragment.getActivity();
|
|
|
|
this.fragment = fragment;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2014-12-06 15:40:22 +01:00
|
|
|
protected ListResponse<ParcelableStatus> doInBackground(final ParcelableStatus... params) {
|
|
|
|
final ArrayList<ParcelableStatus> list = new ArrayList<>();
|
2014-07-28 12:42:48 +02:00
|
|
|
try {
|
|
|
|
ParcelableStatus status = params[0];
|
2014-12-06 15:40:22 +01:00
|
|
|
final long account_id = status.account_id;
|
|
|
|
while (status.in_reply_to_status_id > 0 && !isCancelled()) {
|
2014-07-28 12:42:48 +02:00
|
|
|
status = findStatus(context, account_id, status.in_reply_to_status_id);
|
2014-12-06 15:40:22 +01:00
|
|
|
publishProgress(status);
|
|
|
|
list.add(0, status);
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
|
|
|
} catch (final TwitterException e) {
|
2014-12-06 15:40:22 +01:00
|
|
|
return ListResponse.getListInstance(e);
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
2014-12-06 15:40:22 +01:00
|
|
|
return ListResponse.getListInstance(list);
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onCancelled() {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2014-12-06 15:40:22 +01:00
|
|
|
protected void onPostExecute(final ListResponse<ParcelableStatus> data) {
|
|
|
|
if (data.hasData()) {
|
|
|
|
fragment.setConversation(data.getData());
|
|
|
|
} else {
|
|
|
|
showErrorMessage(context, context.getString(R.string.action_getting_status), data.getException(), true);
|
|
|
|
}
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
|
|
|
|
2014-12-07 16:13:07 +01:00
|
|
|
@Override
|
|
|
|
protected void onProgressUpdate(ParcelableStatus... values) {
|
|
|
|
super.onProgressUpdate(values);
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private static class SpaceViewHolder extends ViewHolder {
|
|
|
|
|
|
|
|
public SpaceViewHolder(View itemView) {
|
|
|
|
super(itemView);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-17 19:58:29 +01:00
|
|
|
private static class DetailStatusViewHolder extends ViewHolder implements OnClickListener,
|
|
|
|
ActionMenuView.OnMenuItemClickListener {
|
2014-12-06 15:40:22 +01:00
|
|
|
|
|
|
|
private final StatusAdapter adapter;
|
|
|
|
|
|
|
|
private final CardView cardView;
|
2014-12-07 16:13:07 +01:00
|
|
|
|
2015-01-17 19:58:29 +01:00
|
|
|
private final ActionMenuView menuBar;
|
2014-12-06 15:40:22 +01:00
|
|
|
private final TextView nameView, screenNameView;
|
|
|
|
private final StatusTextView textView;
|
2014-12-24 05:39:21 +01:00
|
|
|
private final ShapedImageView profileImageView;
|
2014-12-06 15:40:22 +01:00
|
|
|
private final ImageView profileTypeView;
|
|
|
|
private final TextView timeSourceView;
|
|
|
|
private final TextView replyRetweetStatusView;
|
|
|
|
private final View repliesContainer, retweetsContainer, favoritesContainer;
|
|
|
|
private final TextView repliesCountView, retweetsCountView, favoritesCountView;
|
2014-12-07 16:13:07 +01:00
|
|
|
|
|
|
|
private final View profileContainer;
|
|
|
|
private final View mediaPreviewContainer;
|
|
|
|
private final View mediaPreviewLoad;
|
2014-12-06 15:40:22 +01:00
|
|
|
private final LinearLayout mediaPreviewGrid;
|
|
|
|
|
2014-12-07 16:13:07 +01:00
|
|
|
private final View locationContainer;
|
2015-01-03 16:16:50 +01:00
|
|
|
private final TwitterCardContainer twitterCard;
|
2014-12-07 16:13:07 +01:00
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
public DetailStatusViewHolder(StatusAdapter adapter, View itemView) {
|
|
|
|
super(itemView);
|
|
|
|
this.adapter = adapter;
|
|
|
|
cardView = (CardView) itemView.findViewById(R.id.card);
|
2015-01-17 19:58:29 +01:00
|
|
|
menuBar = (ActionMenuView) itemView.findViewById(R.id.menu_bar);
|
2014-12-06 15:40:22 +01:00
|
|
|
nameView = (TextView) itemView.findViewById(R.id.name);
|
|
|
|
screenNameView = (TextView) itemView.findViewById(R.id.screen_name);
|
|
|
|
textView = (StatusTextView) itemView.findViewById(R.id.text);
|
2014-12-24 05:39:21 +01:00
|
|
|
profileImageView = (ShapedImageView) itemView.findViewById(R.id.profile_image);
|
2014-12-06 15:40:22 +01:00
|
|
|
profileTypeView = (ImageView) itemView.findViewById(R.id.profile_type);
|
|
|
|
timeSourceView = (TextView) itemView.findViewById(R.id.time_source);
|
|
|
|
replyRetweetStatusView = (TextView) itemView.findViewById(R.id.reply_retweet_status);
|
|
|
|
repliesContainer = itemView.findViewById(R.id.replies_container);
|
|
|
|
retweetsContainer = itemView.findViewById(R.id.retweets_container);
|
|
|
|
favoritesContainer = itemView.findViewById(R.id.favorites_container);
|
|
|
|
repliesCountView = (TextView) itemView.findViewById(R.id.replies_count);
|
|
|
|
retweetsCountView = (TextView) itemView.findViewById(R.id.retweets_count);
|
|
|
|
favoritesCountView = (TextView) itemView.findViewById(R.id.favorites_count);
|
2014-12-07 16:13:07 +01:00
|
|
|
mediaPreviewContainer = itemView.findViewById(R.id.media_preview);
|
|
|
|
mediaPreviewLoad = itemView.findViewById(R.id.media_preview_load);
|
|
|
|
mediaPreviewGrid = (LinearLayout) itemView.findViewById(R.id.media_preview_grid);
|
|
|
|
locationContainer = itemView.findViewById(R.id.location_container);
|
|
|
|
profileContainer = itemView.findViewById(R.id.profile_container);
|
2015-01-03 16:16:50 +01:00
|
|
|
twitterCard = (TwitterCardContainer) itemView.findViewById(R.id.twitter_card);
|
2014-12-06 15:40:22 +01:00
|
|
|
|
|
|
|
setIsRecyclable(false);
|
|
|
|
initViews();
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2014-12-06 15:40:22 +01:00
|
|
|
public void onClick(View v) {
|
|
|
|
switch (v.getId()) {
|
2014-12-07 16:13:07 +01:00
|
|
|
case R.id.media_preview_load: {
|
|
|
|
adapter.setDetailMediaExpanded(true);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case R.id.profile_container: {
|
2014-12-06 15:40:22 +01:00
|
|
|
final ParcelableStatus status = adapter.getStatus(getPosition());
|
2014-12-07 16:13:07 +01:00
|
|
|
final Fragment fragment = adapter.getFragment();
|
|
|
|
final FragmentActivity activity = fragment.getActivity();
|
|
|
|
final Bundle activityOption = Utils.makeSceneTransitionOption(activity,
|
|
|
|
new Pair<View, String>(profileImageView, UserFragment.TRANSITION_NAME_PROFILE_IMAGE),
|
|
|
|
new Pair<View, String>(profileTypeView, UserFragment.TRANSITION_NAME_PROFILE_TYPE));
|
|
|
|
openUserProfile(activity, status.account_id, status.user_id, status.user_screen_name,
|
|
|
|
activityOption);
|
2014-12-06 15:40:22 +01:00
|
|
|
break;
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
2015-01-08 10:13:20 +01:00
|
|
|
case R.id.retweets_container: {
|
|
|
|
final ParcelableStatus status = adapter.getStatus(getPosition());
|
|
|
|
final Fragment fragment = adapter.getFragment();
|
|
|
|
final FragmentActivity activity = fragment.getActivity();
|
|
|
|
Utils.openStatusRetweeters(activity, status.account_id, status.id);
|
|
|
|
break;
|
|
|
|
}
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2014-12-07 16:13:07 +01:00
|
|
|
public boolean onMenuItemClick(MenuItem item) {
|
|
|
|
final StatusFragment fragment = adapter.getFragment();
|
|
|
|
final ParcelableStatus status = adapter.getStatus(getPosition());
|
|
|
|
if (status == null || fragment == null) return false;
|
|
|
|
final AsyncTwitterWrapper twitter = fragment.getTwitterWrapper();
|
|
|
|
final FragmentActivity activity = fragment.getActivity();
|
|
|
|
switch (item.getItemId()) {
|
|
|
|
case MENU_SHARE: {
|
|
|
|
startStatusShareChooser(activity, status);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case MENU_COPY: {
|
|
|
|
if (ClipboardUtils.setText(activity, status.text_plain)) {
|
|
|
|
showOkMessage(activity, R.string.text_copied, false);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case MENU_RETWEET: {
|
|
|
|
if (isMyRetweet(status)) {
|
2014-12-11 06:40:08 +01:00
|
|
|
twitter.cancelRetweetAsync(status.account_id, status.id, status.my_retweet_id);
|
2014-12-07 16:13:07 +01:00
|
|
|
} else {
|
2014-12-11 06:40:08 +01:00
|
|
|
twitter.retweetStatusAsync(status.account_id, status.id);
|
2014-12-07 16:13:07 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case MENU_QUOTE: {
|
|
|
|
final Intent intent = new Intent(INTENT_ACTION_QUOTE);
|
|
|
|
intent.putExtra(EXTRA_STATUS, status);
|
2014-12-08 16:16:33 +01:00
|
|
|
fragment.startActivity(intent);
|
2014-12-07 16:13:07 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case MENU_REPLY: {
|
|
|
|
final Intent intent = new Intent(INTENT_ACTION_REPLY);
|
|
|
|
intent.putExtra(EXTRA_STATUS, status);
|
2014-12-08 16:16:33 +01:00
|
|
|
fragment.startActivity(intent);
|
2014-12-07 16:13:07 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case MENU_FAVORITE: {
|
|
|
|
if (status.is_favorite) {
|
|
|
|
twitter.destroyFavoriteAsync(status.account_id, status.id);
|
|
|
|
} else {
|
|
|
|
twitter.createFavoriteAsync(status.account_id, status.id);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case MENU_DELETE: {
|
|
|
|
DestroyStatusDialogFragment.show(fragment.getFragmentManager(), status);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case MENU_ADD_TO_FILTER: {
|
|
|
|
AddStatusFilterDialogFragment.show(fragment.getFragmentManager(), status);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case MENU_SET_COLOR: {
|
|
|
|
final Intent intent = new Intent(activity, ColorPickerDialogActivity.class);
|
|
|
|
final int color = getUserColor(activity, status.user_id, true);
|
|
|
|
if (color != 0) {
|
|
|
|
intent.putExtra(EXTRA_COLOR, color);
|
|
|
|
}
|
|
|
|
intent.putExtra(EXTRA_CLEAR_BUTTON, color != 0);
|
|
|
|
intent.putExtra(EXTRA_ALPHA_SLIDER, false);
|
|
|
|
fragment.startActivityForResult(intent, REQUEST_SET_COLOR);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case MENU_CLEAR_NICKNAME: {
|
|
|
|
clearUserNickname(activity, status.user_id);
|
|
|
|
adapter.notifyDataSetChanged();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case MENU_SET_NICKNAME: {
|
|
|
|
final String nick = getUserNickname(activity, status.user_id, true);
|
|
|
|
SetUserNicknameDialogFragment.show(fragment.getFragmentManager(), status.user_id, nick);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case MENU_TRANSLATE: {
|
2014-12-13 16:14:47 +01:00
|
|
|
final ParcelableCredentials account
|
|
|
|
= ParcelableAccount.getCredentials(activity, status.account_id);
|
2015-01-11 10:28:45 +01:00
|
|
|
if (Utils.isOfficialCredentials(activity, account)) {
|
2014-12-07 16:13:07 +01:00
|
|
|
StatusTranslateDialogFragment.show(fragment.getFragmentManager(), status);
|
|
|
|
} else {
|
2015-01-08 10:13:20 +01:00
|
|
|
final Resources resources = fragment.getResources();
|
|
|
|
final Locale locale = resources.getConfiguration().locale;
|
|
|
|
try {
|
|
|
|
final String template = "http://translate.google.com/#%s|%s|%s";
|
|
|
|
final String sourceLang = "auto";
|
|
|
|
final String targetLang = URLEncoder.encode(locale.getLanguage(), HTTP.UTF_8);
|
|
|
|
final String text = URLEncoder.encode(status.text_unescaped, HTTP.UTF_8);
|
|
|
|
final Uri uri = Uri.parse(String.format(Locale.ROOT, template, sourceLang, targetLang, text));
|
|
|
|
final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
|
|
|
|
intent.addCategory(Intent.CATEGORY_BROWSABLE);
|
|
|
|
fragment.startActivity(intent);
|
|
|
|
} catch (UnsupportedEncodingException ignore) {
|
2014-12-07 16:13:07 +01:00
|
|
|
|
2015-01-08 10:13:20 +01:00
|
|
|
}
|
2014-12-07 16:13:07 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case MENU_OPEN_WITH_ACCOUNT: {
|
|
|
|
final Intent intent = new Intent(INTENT_ACTION_SELECT_ACCOUNT);
|
|
|
|
intent.setClass(activity, AccountSelectorActivity.class);
|
|
|
|
intent.putExtra(EXTRA_SINGLE_SELECTION, true);
|
2014-12-08 16:16:33 +01:00
|
|
|
fragment.startActivityForResult(intent, REQUEST_SELECT_ACCOUNT);
|
2014-12-07 16:13:07 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
default: {
|
|
|
|
if (item.getIntent() != null) {
|
|
|
|
try {
|
2014-12-08 16:16:33 +01:00
|
|
|
fragment.startActivity(item.getIntent());
|
2014-12-07 16:13:07 +01:00
|
|
|
} catch (final ActivityNotFoundException e) {
|
|
|
|
Log.w(LOGTAG, e);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
2014-12-06 15:40:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public void showStatus(ParcelableStatus status) {
|
|
|
|
if (status == null) return;
|
2015-01-01 11:38:34 +01:00
|
|
|
final StatusFragment fragment = adapter.getFragment();
|
2014-12-06 15:40:22 +01:00
|
|
|
final Context context = adapter.getContext();
|
|
|
|
final Resources resources = context.getResources();
|
|
|
|
final ImageLoaderWrapper loader = adapter.getImageLoader();
|
|
|
|
final boolean nameFirst = adapter.isNameFirst();
|
|
|
|
final boolean nicknameOnly = adapter.isNicknameOnly();
|
|
|
|
final String nickname = getUserNickname(context, status.user_id, true);
|
|
|
|
if (TextUtils.isEmpty(nickname)) {
|
|
|
|
nameView.setText(status.user_name);
|
|
|
|
} else if (nicknameOnly) {
|
|
|
|
nameView.setText(nickname);
|
|
|
|
} else {
|
|
|
|
nameView.setText(context.getString(R.string.name_with_nickname, status.user_name,
|
|
|
|
nickname));
|
|
|
|
}
|
|
|
|
screenNameView.setText("@" + status.user_screen_name);
|
2014-07-28 12:42:48 +02:00
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
textView.setText(Html.fromHtml(status.text_html));
|
|
|
|
final TwidereLinkify linkify = new TwidereLinkify(new OnLinkClickHandler(context, null));
|
|
|
|
linkify.applyAllLinks(textView, status.account_id, status.is_possibly_sensitive);
|
|
|
|
ThemeUtils.applyParagraphSpacing(textView, 1.1f);
|
2014-07-28 12:42:48 +02:00
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
textView.setMovementMethod(StatusContentMovementMethod.getInstance());
|
|
|
|
// textView.setCustomSelectionActionModeCallback(this);
|
2014-07-28 12:42:48 +02:00
|
|
|
|
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
final String timeString = formatToLongTimeString(context, status.timestamp);
|
|
|
|
final String sourceHtml = status.source;
|
|
|
|
if (!isEmpty(timeString) && !isEmpty(sourceHtml)) {
|
|
|
|
timeSourceView.setText(Html.fromHtml(context.getString(R.string.time_source,
|
|
|
|
timeString, sourceHtml)));
|
|
|
|
} else if (isEmpty(timeString) && !isEmpty(sourceHtml)) {
|
|
|
|
timeSourceView.setText(Html.fromHtml(context.getString(R.string.source,
|
|
|
|
sourceHtml)));
|
|
|
|
} else if (!isEmpty(timeString) && isEmpty(sourceHtml)) {
|
|
|
|
timeSourceView.setText(timeString);
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
2014-12-06 15:40:22 +01:00
|
|
|
timeSourceView.setMovementMethod(LinkMovementMethod.getInstance());
|
|
|
|
|
|
|
|
|
|
|
|
retweetsContainer.setVisibility(!status.user_is_protected ? View.VISIBLE : View.GONE);
|
|
|
|
repliesContainer.setVisibility(status.reply_count < 0 ? View.GONE : View.VISIBLE);
|
|
|
|
final Locale locale = context.getResources().getConfiguration().locale;
|
|
|
|
repliesCountView.setText(getLocalizedNumber(locale, status.reply_count));
|
|
|
|
retweetsCountView.setText(getLocalizedNumber(locale, status.retweet_count));
|
|
|
|
favoritesCountView.setText(getLocalizedNumber(locale, status.favorite_count));
|
|
|
|
|
|
|
|
loader.displayProfileImage(profileImageView, status.user_profile_image_url);
|
|
|
|
|
|
|
|
final int typeIconRes = getUserTypeIconRes(status.user_is_verified, status.user_is_protected);
|
|
|
|
if (typeIconRes != 0) {
|
|
|
|
profileTypeView.setImageResource(typeIconRes);
|
|
|
|
profileTypeView.setVisibility(View.VISIBLE);
|
|
|
|
} else {
|
|
|
|
profileTypeView.setImageDrawable(null);
|
|
|
|
profileTypeView.setVisibility(View.GONE);
|
|
|
|
}
|
|
|
|
|
2014-12-07 16:13:07 +01:00
|
|
|
if (status.media == null) {
|
|
|
|
mediaPreviewContainer.setVisibility(View.GONE);
|
|
|
|
} else if (adapter.isDetailMediaExpanded()) {
|
|
|
|
mediaPreviewContainer.setVisibility(View.VISIBLE);
|
|
|
|
mediaPreviewLoad.setVisibility(View.GONE);
|
2014-12-06 15:40:22 +01:00
|
|
|
mediaPreviewGrid.setVisibility(View.VISIBLE);
|
|
|
|
mediaPreviewGrid.removeAllViews();
|
2014-12-07 16:13:07 +01:00
|
|
|
final int maxColumns = resources.getInteger(R.integer.grid_column_image_preview);
|
2015-01-11 10:28:45 +01:00
|
|
|
Utils.addToLinearLayout(mediaPreviewGrid, loader, status.media, status.account_id,
|
|
|
|
maxColumns, adapter.getFragment());
|
2014-12-06 15:40:22 +01:00
|
|
|
} else {
|
2014-12-07 16:13:07 +01:00
|
|
|
mediaPreviewContainer.setVisibility(View.VISIBLE);
|
|
|
|
mediaPreviewLoad.setVisibility(View.VISIBLE);
|
2014-12-06 15:40:22 +01:00
|
|
|
mediaPreviewGrid.setVisibility(View.GONE);
|
|
|
|
mediaPreviewGrid.removeAllViews();
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
2015-01-01 11:38:34 +01:00
|
|
|
|
2015-01-03 16:16:50 +01:00
|
|
|
if (TwitterCardUtils.isCardSupported(status.card)) {
|
|
|
|
final Point size = TwitterCardUtils.getCardSize(status.card);
|
2015-01-01 11:38:34 +01:00
|
|
|
twitterCard.setVisibility(View.VISIBLE);
|
2015-01-03 16:16:50 +01:00
|
|
|
if (size != null) {
|
|
|
|
twitterCard.setCardSize(size.x, size.y);
|
|
|
|
} else {
|
|
|
|
twitterCard.setCardSize(0, 0);
|
|
|
|
}
|
|
|
|
final Fragment cardFragment = TwitterCardUtils.createCardFragment(status.card);
|
2015-01-01 11:38:34 +01:00
|
|
|
final FragmentManager fm = fragment.getChildFragmentManager();
|
|
|
|
final FragmentTransaction ft = fm.beginTransaction();
|
|
|
|
ft.replace(R.id.twitter_card, cardFragment);
|
|
|
|
ft.commit();
|
|
|
|
} else {
|
|
|
|
twitterCard.setVisibility(View.GONE);
|
|
|
|
final FragmentManager fm = fragment.getChildFragmentManager();
|
|
|
|
// final FragmentTransaction ft = fm.beginTransaction();
|
|
|
|
}
|
|
|
|
|
2015-01-17 19:58:29 +01:00
|
|
|
Utils.setMenuForStatus(context, menuBar.getMenu(), status, adapter.getStatusAccount());
|
2014-12-06 15:40:22 +01:00
|
|
|
}
|
2014-12-07 16:13:07 +01:00
|
|
|
|
|
|
|
private void initViews() {
|
2015-01-17 19:58:29 +01:00
|
|
|
// menuBar.setOnMenuItemClickListener(this);
|
2014-12-07 16:13:07 +01:00
|
|
|
menuBar.setOnMenuItemClickListener(this);
|
2015-01-17 19:58:29 +01:00
|
|
|
final FragmentActivity activity = adapter.getFragment().getActivity();
|
|
|
|
final MenuInflater inflater = activity.getMenuInflater();
|
|
|
|
inflater.inflate(R.menu.menu_status, menuBar.getMenu());
|
|
|
|
ThemeUtils.wrapMenuIcon(menuBar, MENU_GROUP_STATUS_SHARE);
|
2014-12-07 16:13:07 +01:00
|
|
|
mediaPreviewLoad.setOnClickListener(this);
|
|
|
|
profileContainer.setOnClickListener(this);
|
|
|
|
|
2015-01-08 10:13:20 +01:00
|
|
|
retweetsContainer.setOnClickListener(this);
|
|
|
|
|
2014-12-24 05:39:21 +01:00
|
|
|
final float defaultTextSize = adapter.getTextSize();
|
2014-12-10 13:15:09 +01:00
|
|
|
nameView.setTextSize(defaultTextSize * 1.25f);
|
|
|
|
textView.setTextSize(defaultTextSize * 1.25f);
|
|
|
|
screenNameView.setTextSize(defaultTextSize * 0.85f);
|
|
|
|
timeSourceView.setTextSize(defaultTextSize * 0.85f);
|
2014-12-07 16:13:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-12-06 15:40:22 +01:00
|
|
|
}
|
|
|
|
|
2014-12-08 16:16:33 +01:00
|
|
|
private static class StatusListLinearLayoutManager extends LinearLayoutManager {
|
2014-12-06 15:40:22 +01:00
|
|
|
|
2014-12-07 16:13:07 +01:00
|
|
|
private final RecyclerView recyclerView;
|
|
|
|
|
2014-12-08 16:16:33 +01:00
|
|
|
public StatusListLinearLayoutManager(Context context, RecyclerView recyclerView) {
|
2014-12-06 15:40:22 +01:00
|
|
|
super(context);
|
2014-12-08 16:16:33 +01:00
|
|
|
setOrientation(LinearLayoutManager.VERTICAL);
|
2014-12-07 16:13:07 +01:00
|
|
|
this.recyclerView = recyclerView;
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2014-12-06 15:40:22 +01:00
|
|
|
public int getDecoratedMeasuredHeight(View child) {
|
|
|
|
final int height = super.getDecoratedMeasuredHeight(child);
|
|
|
|
int heightBeforeSpace = 0;
|
|
|
|
if (getItemViewType(child) == StatusAdapter.VIEW_TYPE_SPACE) {
|
|
|
|
for (int i = 0, j = getChildCount(); i < j; i++) {
|
|
|
|
final View childToMeasure = getChildAt(i);
|
|
|
|
final LayoutParams paramsToMeasure = (LayoutParams) childToMeasure.getLayoutParams();
|
|
|
|
final int typeToMeasure = getItemViewType(childToMeasure);
|
|
|
|
if (typeToMeasure == StatusAdapter.VIEW_TYPE_DETAIL_STATUS || heightBeforeSpace != 0) {
|
|
|
|
heightBeforeSpace += super.getDecoratedMeasuredHeight(childToMeasure)
|
|
|
|
+ paramsToMeasure.topMargin + paramsToMeasure.bottomMargin;
|
|
|
|
}
|
|
|
|
if (typeToMeasure == StatusAdapter.VIEW_TYPE_REPLIES_LOAD_INDICATOR) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (heightBeforeSpace != 0) {
|
2014-12-07 16:13:07 +01:00
|
|
|
final int spaceHeight = recyclerView.getMeasuredHeight() - heightBeforeSpace;
|
2014-12-06 15:40:22 +01:00
|
|
|
return Math.max(0, spaceHeight);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return height;
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
|
|
|
|
2015-01-01 11:38:34 +01:00
|
|
|
@Override
|
|
|
|
public void setOrientation(int orientation) {
|
|
|
|
if (orientation != VERTICAL)
|
|
|
|
throw new IllegalArgumentException("Only VERTICAL orientation supported");
|
|
|
|
super.setOrientation(orientation);
|
|
|
|
}
|
|
|
|
|
2014-07-28 12:42:48 +02:00
|
|
|
}
|
2014-12-07 16:13:07 +01:00
|
|
|
|
2014-07-03 07:48:39 +02:00
|
|
|
}
|