implementing link highlighting

fixed some crashes under rare conditions
This commit is contained in:
Mariotaku Lee 2015-04-06 01:58:10 +08:00
parent 8eb4ee994b
commit 490b1d3aef
25 changed files with 592 additions and 257 deletions

View File

@ -302,7 +302,8 @@ public class CustomTabEditorActivity extends BaseSupportDialogActivity implement
mAccountsAdapter.add(ParcelableAccount.dummyInstance()); mAccountsAdapter.add(ParcelableAccount.dummyInstance());
} }
final boolean officialKeyOnly = intent.getBooleanExtra(EXTRA_OFFICIAL_KEY_ONLY, false); final boolean officialKeyOnly = intent.getBooleanExtra(EXTRA_OFFICIAL_KEY_ONLY, false);
mAccountsAdapter.addAll(ParcelableAccount.getAccountsList(this, false, officialKeyOnly)); final boolean forcePrivateAPIs = intent.getBooleanExtra(KEY_FORCE_USING_PRIVATE_APIS, false);
mAccountsAdapter.addAll(ParcelableAccount.getAccountsList(this, false, !forcePrivateAPIs && officialKeyOnly));
mAccountsAdapter.setDummyItemText(R.string.activated_accounts); mAccountsAdapter.setDummyItemText(R.string.activated_accounts);
switch (conf.getSecondaryFieldType()) { switch (conf.getSecondaryFieldType()) {
case CustomTabConfiguration.FIELD_TYPE_USER: { case CustomTabConfiguration.FIELD_TYPE_USER: {

View File

@ -32,6 +32,7 @@ import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment; import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
@ -295,11 +296,13 @@ public class DraftsActivity extends BaseActionBarActivity implements LoaderCallb
private final FragmentActivity mActivity; private final FragmentActivity mActivity;
private final long[] mIds; private final long[] mIds;
private final NotificationManager mNotificationManager; private final NotificationManager mNotificationManager;
private Handler mHandler;
private DeleteDraftsTask(final FragmentActivity activity, final long[] ids) { private DeleteDraftsTask(final FragmentActivity activity, final long[] ids) {
mActivity = activity; mActivity = activity;
mNotificationManager = (NotificationManager) activity.getSystemService(NOTIFICATION_SERVICE); mNotificationManager = (NotificationManager) activity.getSystemService(NOTIFICATION_SERVICE);
mIds = ids; mIds = ids;
mHandler = new Handler(activity.getMainLooper());
} }
@Override @Override
@ -345,9 +348,14 @@ public class DraftsActivity extends BaseActionBarActivity implements LoaderCallb
@Override @Override
protected void onPreExecute() { protected void onPreExecute() {
super.onPreExecute(); super.onPreExecute();
mHandler.post(new Runnable() {
@Override
public void run() {
final SupportProgressDialogFragment f = SupportProgressDialogFragment.show(mActivity, final SupportProgressDialogFragment f = SupportProgressDialogFragment.show(mActivity,
FRAGMENT_TAG_DELETING_DRAFTS); FRAGMENT_TAG_DELETING_DRAFTS);
f.setCancelable(false); f.setCancelable(false);
} }
});
}
} }
} }

View File

@ -25,6 +25,7 @@ import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.DialogFragment; import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.view.View; import android.view.View;
@ -232,14 +233,17 @@ public class UserListSelectorActivity extends BaseSupportDialogActivity implemen
private static class GetUserListsTask extends AsyncTask<Void, Void, SingleResponse<List<ParcelableUserList>>> { private static class GetUserListsTask extends AsyncTask<Void, Void, SingleResponse<List<ParcelableUserList>>> {
private static final String FRAGMENT_TAG_GET_USER_LISTS = "get_user_lists"; private static final String FRAGMENT_TAG_GET_USER_LISTS = "get_user_lists";
private final UserListSelectorActivity mActivity; private final UserListSelectorActivity mActivity;
private final Handler mHandler;
private final long mAccountId; private final long mAccountId;
private final String mScreenName; private final String mScreenName;
GetUserListsTask(final UserListSelectorActivity activity, final long account_id, final String screen_name) { GetUserListsTask(final UserListSelectorActivity activity, final long accountId, final String screenName) {
mActivity = activity; mActivity = activity;
mAccountId = account_id; mHandler = new Handler(activity.getMainLooper());
mScreenName = screen_name; mAccountId = accountId;
mScreenName = screenName;
} }
@Override @Override
@ -248,7 +252,7 @@ public class UserListSelectorActivity extends BaseSupportDialogActivity implemen
if (twitter == null) return SingleResponse.getInstance(); if (twitter == null) return SingleResponse.getInstance();
try { try {
final ResponseList<UserList> lists = twitter.getUserLists(mScreenName, true); final ResponseList<UserList> lists = twitter.getUserLists(mScreenName, true);
final List<ParcelableUserList> data = new ArrayList<ParcelableUserList>(); final List<ParcelableUserList> data = new ArrayList<>();
boolean is_my_account = mScreenName.equalsIgnoreCase(getAccountScreenName(mActivity, mAccountId)); boolean is_my_account = mScreenName.equalsIgnoreCase(getAccountScreenName(mActivity, mAccountId));
for (final UserList item : lists) { for (final UserList item : lists) {
final User user = item.getUser(); final User user = item.getUser();
@ -286,7 +290,13 @@ public class UserListSelectorActivity extends BaseSupportDialogActivity implemen
@Override @Override
protected void onPreExecute() { protected void onPreExecute() {
SupportProgressDialogFragment.show(mActivity, FRAGMENT_TAG_GET_USER_LISTS).setCancelable(false); mHandler.post(new Runnable() {
@Override
public void run() {
final SupportProgressDialogFragment df = SupportProgressDialogFragment.show(mActivity, FRAGMENT_TAG_GET_USER_LISTS);
df.setCancelable(false);
}
});
} }
} }
@ -295,12 +305,15 @@ public class UserListSelectorActivity extends BaseSupportDialogActivity implemen
private static final String FRAGMENT_TAG_SEARCH_USERS = "search_users"; private static final String FRAGMENT_TAG_SEARCH_USERS = "search_users";
private final UserListSelectorActivity mActivity; private final UserListSelectorActivity mActivity;
private final Handler mHandler;
private final long mAccountId; private final long mAccountId;
private final String mName; private final String mName;
SearchUsersTask(final UserListSelectorActivity activity, final long account_id, final String name) { SearchUsersTask(final UserListSelectorActivity activity, final long accountId, final String name) {
mActivity = activity; mActivity = activity;
mAccountId = account_id; mHandler = new Handler(activity.getMainLooper());
mAccountId = accountId;
mName = name; mName = name;
} }
@ -334,7 +347,13 @@ public class UserListSelectorActivity extends BaseSupportDialogActivity implemen
@Override @Override
protected void onPreExecute() { protected void onPreExecute() {
SupportProgressDialogFragment.show(mActivity, FRAGMENT_TAG_SEARCH_USERS).setCancelable(false); mHandler.post(new Runnable() {
@Override
public void run() {
final SupportProgressDialogFragment df = SupportProgressDialogFragment.show(mActivity, FRAGMENT_TAG_SEARCH_USERS);
df.setCancelable(false);
}
});
} }
} }

View File

@ -24,6 +24,7 @@ import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.DialogFragment; import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager; import android.support.v4.app.LoaderManager;
@ -425,6 +426,7 @@ public class UserProfileEditorActivity extends BaseActionBarActivity implements
private static final String DIALOG_FRAGMENT_TAG = "updating_user_profile"; private static final String DIALOG_FRAGMENT_TAG = "updating_user_profile";
private final UserProfileEditorActivity mActivity; private final UserProfileEditorActivity mActivity;
private final Handler mHandler;
private final long mAccountId; private final long mAccountId;
private final ParcelableUser mOriginal; private final ParcelableUser mOriginal;
private final String mName; private final String mName;
@ -440,6 +442,7 @@ public class UserProfileEditorActivity extends BaseActionBarActivity implements
final String description, final int linkColor, final String description, final int linkColor,
final int backgroundColor) { final int backgroundColor) {
mActivity = activity; mActivity = activity;
mHandler = new Handler(activity.getMainLooper());
mAccountId = accountId; mAccountId = accountId;
mOriginal = original; mOriginal = original;
mName = name; mName = name;
@ -504,8 +507,13 @@ public class UserProfileEditorActivity extends BaseActionBarActivity implements
@Override @Override
protected void onPreExecute() { protected void onPreExecute() {
mHandler.post(new Runnable() {
@Override
public void run() {
final DialogFragment df = SupportProgressDialogFragment.show(mActivity, DIALOG_FRAGMENT_TAG); final DialogFragment df = SupportProgressDialogFragment.show(mActivity, DIALOG_FRAGMENT_TAG);
df.setCancelable(false); df.setCancelable(false);
}
});
super.onPreExecute(); super.onPreExecute();
} }

View File

@ -44,18 +44,21 @@ import org.mariotaku.twidere.util.ImageLoadingHandler;
import org.mariotaku.twidere.util.MediaLoaderWrapper; import org.mariotaku.twidere.util.MediaLoaderWrapper;
import org.mariotaku.twidere.util.SharedPreferencesWrapper; import org.mariotaku.twidere.util.SharedPreferencesWrapper;
import org.mariotaku.twidere.util.ThemeUtils; import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.TwidereLinkify;
import org.mariotaku.twidere.util.TwidereLinkify.OnLinkClickListener;
import org.mariotaku.twidere.util.Utils; import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.holder.ActivityTitleSummaryViewHolder; import org.mariotaku.twidere.view.holder.ActivityTitleSummaryViewHolder;
import org.mariotaku.twidere.view.holder.GapViewHolder; import org.mariotaku.twidere.view.holder.GapViewHolder;
import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder; import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder;
import org.mariotaku.twidere.view.holder.StatusViewHolder; import org.mariotaku.twidere.view.holder.StatusViewHolder;
import org.mariotaku.twidere.view.holder.StatusViewHolder.DummyStatusHolderAdapter;
import org.mariotaku.twidere.view.holder.StatusViewHolder.StatusClickListener; import org.mariotaku.twidere.view.holder.StatusViewHolder.StatusClickListener;
/** /**
* Created by mariotaku on 15/1/3. * Created by mariotaku on 15/1/3.
*/ */
public abstract class AbsActivitiesAdapter<Data> extends Adapter<ViewHolder> implements Constants, public abstract class AbsActivitiesAdapter<Data> extends Adapter<ViewHolder> implements Constants,
IActivitiesAdapter<Data>, StatusClickListener { IActivitiesAdapter<Data>, StatusClickListener, OnLinkClickListener {
private static final int ITEM_VIEW_TYPE_STUB = 0; private static final int ITEM_VIEW_TYPE_STUB = 0;
private static final int ITEM_VIEW_TYPE_GAP = 1; private static final int ITEM_VIEW_TYPE_GAP = 1;
@ -70,11 +73,13 @@ public abstract class AbsActivitiesAdapter<Data> extends Adapter<ViewHolder> imp
private final AsyncTwitterWrapper mTwitterWrapper; private final AsyncTwitterWrapper mTwitterWrapper;
private final int mCardBackgroundColor; private final int mCardBackgroundColor;
private final int mTextSize; private final int mTextSize;
private final int mProfileImageStyle, mMediaPreviewStyle; private final int mProfileImageStyle, mMediaPreviewStyle, mLinkHighlightingStyle;
private final boolean mCompactCards; private final boolean mCompactCards;
private final boolean mDisplayMediaPreview; private final boolean mDisplayMediaPreview;
private final boolean mNameFirst; private final boolean mNameFirst;
private final boolean mDisplayProfileImage; private final boolean mDisplayProfileImage;
private final TwidereLinkify mLinkify;
private final DummyStatusHolderAdapter mStatusAdapterDelegate;
private boolean mLoadMoreSupported; private boolean mLoadMoreSupported;
private boolean mLoadMoreIndicatorVisible; private boolean mLoadMoreIndicatorVisible;
private ActivityAdapterListener mActivityAdapterListener; private ActivityAdapterListener mActivityAdapterListener;
@ -93,9 +98,12 @@ public abstract class AbsActivitiesAdapter<Data> extends Adapter<ViewHolder> imp
mCompactCards = compact; mCompactCards = compact;
mProfileImageStyle = Utils.getProfileImageStyle(preferences.getString(KEY_PROFILE_IMAGE_STYLE, null)); mProfileImageStyle = Utils.getProfileImageStyle(preferences.getString(KEY_PROFILE_IMAGE_STYLE, null));
mMediaPreviewStyle = Utils.getMediaPreviewStyle(preferences.getString(KEY_MEDIA_PREVIEW_STYLE, null)); mMediaPreviewStyle = Utils.getMediaPreviewStyle(preferences.getString(KEY_MEDIA_PREVIEW_STYLE, null));
mLinkHighlightingStyle = Utils.getLinkHighlightingStyleInt(preferences.getString(KEY_LINK_HIGHLIGHT_OPTION, null));
mDisplayProfileImage = preferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE, true); mDisplayProfileImage = preferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE, true);
mDisplayMediaPreview = preferences.getBoolean(KEY_MEDIA_PREVIEW, false); mDisplayMediaPreview = preferences.getBoolean(KEY_MEDIA_PREVIEW, false);
mNameFirst = preferences.getBoolean(KEY_NAME_FIRST, true); mNameFirst = preferences.getBoolean(KEY_NAME_FIRST, true);
mLinkify = new TwidereLinkify(this);
mStatusAdapterDelegate = new DummyStatusHolderAdapter(context);
} }
public abstract ParcelableActivity getActivity(int position); public abstract ParcelableActivity getActivity(int position);
@ -141,10 +149,88 @@ public abstract class AbsActivitiesAdapter<Data> extends Adapter<ViewHolder> imp
return mTextSize; return mTextSize;
} }
@Override
public boolean isLoadMoreIndicatorVisible() {
return mLoadMoreIndicatorVisible;
}
@Override
public boolean isLoadMoreSupported() {
return mLoadMoreSupported;
}
@Override
public void setLoadMoreSupported(boolean supported) {
mLoadMoreSupported = supported;
if (!supported) {
mLoadMoreIndicatorVisible = false;
}
notifyDataSetChanged();
}
@Override
public void setLoadMoreIndicatorVisible(boolean enabled) {
if (mLoadMoreIndicatorVisible == enabled) return;
mLoadMoreIndicatorVisible = enabled && mLoadMoreSupported;
notifyDataSetChanged();
}
public int getLinkHighlightingStyle() {
return mLinkHighlightingStyle;
}
public TwidereLinkify getLinkify() {
return mLinkify;
}
public boolean isNameFirst() { public boolean isNameFirst() {
return mNameFirst; return mNameFirst;
} }
@Override
public boolean isProfileImageEnabled() {
return mDisplayProfileImage;
}
@Override
public void onStatusClick(StatusViewHolder holder, int position) {
final ParcelableActivity activity = getActivity(position);
final ParcelableStatus status;
if (activity.action == ParcelableActivity.ACTION_MENTION) {
status = activity.target_object_statuses[0];
} else {
status = activity.target_statuses[0];
}
Utils.openStatus(getContext(), status, null);
}
@Override
public void onMediaClick(StatusViewHolder holder, ParcelableMedia media, int position) {
}
@Override
public void onUserProfileClick(StatusViewHolder holder, int position) {
final Context context = getContext();
final ParcelableActivity activity = getActivity(position);
final ParcelableStatus status;
if (activity.action == ParcelableActivity.ACTION_MENTION) {
status = activity.target_object_statuses[0];
} else {
status = activity.target_statuses[0];
}
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);
}
}
@Override @Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) { switch (viewType) {
@ -159,7 +245,7 @@ public abstract class AbsActivitiesAdapter<Data> extends Adapter<ViewHolder> imp
final CardView cardView = (CardView) view.findViewById(R.id.card); final CardView cardView = (CardView) view.findViewById(R.id.card);
cardView.setCardBackgroundColor(mCardBackgroundColor); cardView.setCardBackgroundColor(mCardBackgroundColor);
} }
final StatusViewHolder holder = new StatusViewHolder(view); final StatusViewHolder holder = new StatusViewHolder(mStatusAdapterDelegate, view);
holder.setTextSize(getTextSize()); holder.setTextSize(getTextSize());
holder.setStatusClickListener(this); holder.setStatusClickListener(this);
return holder; return holder;
@ -204,9 +290,7 @@ public abstract class AbsActivitiesAdapter<Data> extends Adapter<ViewHolder> imp
status = activity.target_statuses[0]; status = activity.target_statuses[0];
} }
final StatusViewHolder statusViewHolder = (StatusViewHolder) holder; final StatusViewHolder statusViewHolder = (StatusViewHolder) holder;
statusViewHolder.displayStatus(getContext(), getImageLoader(), getImageLoadingHandler(), statusViewHolder.displayStatus(status, null, true, true);
getTwitterWrapper(), isProfileImageEnabled(), isMediaPreviewEnabled(), false, false, isNameFirst(),
getProfileImageStyle(), getMediaPreviewStyle(), status, null, true);
break; break;
} }
case ITEM_VIEW_TYPE_TITLE_SUMMARY: { case ITEM_VIEW_TYPE_TITLE_SUMMARY: {
@ -255,13 +339,6 @@ public abstract class AbsActivitiesAdapter<Data> extends Adapter<ViewHolder> imp
} }
} }
@Override
public void onMediaClick(StatusViewHolder holder, ParcelableMedia media, int position) {
}
@Override @Override
public void onItemActionClick(ViewHolder holder, int id, int position) { public void onItemActionClick(ViewHolder holder, int id, int position) {
@ -273,70 +350,14 @@ public abstract class AbsActivitiesAdapter<Data> extends Adapter<ViewHolder> imp
} }
@Override @Override
public void onUserProfileClick(StatusViewHolder holder, int position) { public void onLinkClick(String link, String orig, long accountId, long extraId, int type, boolean sensitive, int start, int end) {
final Context context = getContext();
final ParcelableActivity activity = getActivity(position);
final ParcelableStatus status;
if (activity.action == ParcelableActivity.ACTION_MENTION) {
status = activity.target_object_statuses[0];
} else {
status = activity.target_statuses[0];
}
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);
}
}
@Override
public void onStatusClick(StatusViewHolder holder, int position) {
final ParcelableActivity activity = getActivity(position);
final ParcelableStatus status;
if (activity.action == ParcelableActivity.ACTION_MENTION) {
status = activity.target_object_statuses[0];
} else {
status = activity.target_statuses[0];
}
Utils.openStatus(getContext(), status, null);
} }
public void setListener(ActivityAdapterListener listener) { public void setListener(ActivityAdapterListener listener) {
mActivityAdapterListener = listener; mActivityAdapterListener = listener;
} }
@Override
public boolean isLoadMoreIndicatorVisible() {
return mLoadMoreIndicatorVisible;
}
@Override
public boolean isLoadMoreSupported() {
return mLoadMoreSupported;
}
@Override
public void setLoadMoreSupported(boolean supported) {
mLoadMoreSupported = supported;
if (!supported) {
mLoadMoreIndicatorVisible = false;
}
notifyDataSetChanged();
}
@Override
public void setLoadMoreIndicatorVisible(boolean enabled) {
if (mLoadMoreIndicatorVisible == enabled) return;
mLoadMoreIndicatorVisible = enabled && mLoadMoreSupported;
notifyDataSetChanged();
}
protected abstract void bindTitleSummaryViewHolder(ActivityTitleSummaryViewHolder holder, int position); protected abstract void bindTitleSummaryViewHolder(ActivityTitleSummaryViewHolder holder, int position);
protected abstract int getActivityAction(int position); protected abstract int getActivityAction(int position);
@ -345,11 +366,6 @@ public abstract class AbsActivitiesAdapter<Data> extends Adapter<ViewHolder> imp
return mDisplayMediaPreview; return mDisplayMediaPreview;
} }
@Override
public boolean isProfileImageEnabled() {
return mDisplayProfileImage;
}
public static interface ActivityAdapterListener { public static interface ActivityAdapterListener {
void onGapClick(GapViewHolder holder, int position); void onGapClick(GapViewHolder holder, int position);
} }

View File

@ -1,6 +1,9 @@
package org.mariotaku.twidere.adapter; package org.mariotaku.twidere.adapter;
import android.content.ActivityNotFoundException;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentActivity;
import android.support.v4.util.Pair; import android.support.v4.util.Pair;
@ -21,23 +24,33 @@ import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.util.AsyncTwitterWrapper; import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.ImageLoadingHandler; import org.mariotaku.twidere.util.ImageLoadingHandler;
import org.mariotaku.twidere.util.MediaLoaderWrapper; import org.mariotaku.twidere.util.MediaLoaderWrapper;
import org.mariotaku.twidere.util.OnLinkClickHandler;
import org.mariotaku.twidere.util.SharedPreferencesWrapper; import org.mariotaku.twidere.util.SharedPreferencesWrapper;
import org.mariotaku.twidere.util.StatusLinkClickHandler;
import org.mariotaku.twidere.util.ThemeUtils; import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.TwidereLinkify;
import org.mariotaku.twidere.util.TwidereLinkify.HighlightStyle;
import org.mariotaku.twidere.util.TwidereLinkify.OnLinkClickListener;
import org.mariotaku.twidere.util.Utils; import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.CardMediaContainer.PreviewStyle;
import org.mariotaku.twidere.view.ShapedImageView.ShapeStyle;
import org.mariotaku.twidere.view.holder.GapViewHolder; import org.mariotaku.twidere.view.holder.GapViewHolder;
import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder; import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder;
import org.mariotaku.twidere.view.holder.StatusViewHolder; import org.mariotaku.twidere.view.holder.StatusViewHolder;
import edu.tsinghua.spice.Utilies.SpiceProfilingUtil;
import edu.tsinghua.spice.Utilies.TypeMappingUtil;
import edu.ucdavis.earlybird.ProfilingUtil;
/** /**
* Created by mariotaku on 14/11/19. * Created by mariotaku on 14/11/19.
*/ */
public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implements Constants, public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implements Constants,
IStatusesAdapter<D> { IStatusesAdapter<D>, OnLinkClickListener {
public static final int ITEM_VIEW_TYPE_STATUS = 0; public static final int ITEM_VIEW_TYPE_STATUS = 0;
public static final int ITEM_VIEW_TYPE_GAP = 1; public static final int ITEM_VIEW_TYPE_GAP = 1;
public static final int ITEM_VIEW_TYPE_LOAD_INDICATOR = 2; public static final int ITEM_VIEW_TYPE_LOAD_INDICATOR = 2;
private final Context mContext; private final Context mContext;
private final LayoutInflater mInflater; private final LayoutInflater mInflater;
private final MediaLoaderWrapper mImageLoader; private final MediaLoaderWrapper mImageLoader;
@ -45,12 +58,18 @@ public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implemen
private final AsyncTwitterWrapper mTwitterWrapper; private final AsyncTwitterWrapper mTwitterWrapper;
private final int mCardBackgroundColor; private final int mCardBackgroundColor;
private final int mTextSize; private final int mTextSize;
private final int mProfileImageStyle, mMediaPreviewStyle; @ShapeStyle
private final int mProfileImageStyle;
@PreviewStyle
private final int mMediaPreviewStyle;
@HighlightStyle
private final int mLinkHighlightingStyle;
private final boolean mCompactCards; private final boolean mCompactCards;
private final boolean mNameFirst; private final boolean mNameFirst;
private final boolean mDisplayMediaPreview; private final boolean mDisplayMediaPreview;
private final boolean mDisplayProfileImage; private final boolean mDisplayProfileImage;
private final TwidereLinkify mLinkify;
private boolean mLoadMoreSupported; private boolean mLoadMoreSupported;
private boolean mLoadMoreIndicatorVisible; private boolean mLoadMoreIndicatorVisible;
@ -73,9 +92,12 @@ public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implemen
mCompactCards = compact; mCompactCards = compact;
mProfileImageStyle = Utils.getProfileImageStyle(preferences.getString(KEY_PROFILE_IMAGE_STYLE, null)); mProfileImageStyle = Utils.getProfileImageStyle(preferences.getString(KEY_PROFILE_IMAGE_STYLE, null));
mMediaPreviewStyle = Utils.getMediaPreviewStyle(preferences.getString(KEY_MEDIA_PREVIEW_STYLE, null)); mMediaPreviewStyle = Utils.getMediaPreviewStyle(preferences.getString(KEY_MEDIA_PREVIEW_STYLE, null));
mLinkHighlightingStyle = Utils.getLinkHighlightingStyleInt(preferences.getString(KEY_LINK_HIGHLIGHT_OPTION, null));
mNameFirst = preferences.getBoolean(KEY_NAME_FIRST, true); mNameFirst = preferences.getBoolean(KEY_NAME_FIRST, true);
mDisplayProfileImage = preferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE, true); mDisplayProfileImage = preferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE, true);
mDisplayMediaPreview = preferences.getBoolean(KEY_MEDIA_PREVIEW, false); mDisplayMediaPreview = preferences.getBoolean(KEY_MEDIA_PREVIEW, false);
mLinkify = new TwidereLinkify(new InternalOnLinkClickListener(this));
mLinkify.setHighlightOption(mLinkHighlightingStyle);
setShowInReplyTo(true); setShowInReplyTo(true);
} }
@ -149,11 +171,21 @@ public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implemen
notifyDataSetChanged(); notifyDataSetChanged();
} }
@Override
public TwidereLinkify getTwidereLinkify() {
return mLinkify;
}
@Override @Override
public boolean isMediaPreviewEnabled() { public boolean isMediaPreviewEnabled() {
return mDisplayMediaPreview; return mDisplayMediaPreview;
} }
@Override
public int getLinkHighlightingStyle() {
return mLinkHighlightingStyle;
}
@Override @Override
public boolean isNameFirst() { public boolean isNameFirst() {
return mNameFirst; return mNameFirst;
@ -285,6 +317,23 @@ public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implemen
} }
} }
@Override
public void onLinkClick(String link, String orig, long accountId, long extraId, int type, boolean sensitive, int start, int end) {
final Context context = getContext();
// UCD
ProfilingUtil.profile(context, accountId, "Click, " + link + ", " + type);
//spice
SpiceProfilingUtil.profile(context, accountId, accountId + ",Visit," + link + "," + TypeMappingUtil.getLinkType(type));
//end
final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(link));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
context.startActivity(intent);
} catch (final ActivityNotFoundException e) {
// TODO
}
}
public void setListener(StatusAdapterListener listener) { public void setListener(StatusAdapterListener listener) {
mStatusAdapterListener = listener; mStatusAdapterListener = listener;
} }
@ -309,4 +358,21 @@ public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implemen
void onStatusMenuClick(StatusViewHolder holder, View menuView, int position); void onStatusMenuClick(StatusViewHolder holder, View menuView, int position);
} }
private static class InternalOnLinkClickListener<D> extends OnLinkClickHandler {
private final AbsStatusesAdapter<D> adapter;
public InternalOnLinkClickListener(AbsStatusesAdapter<D> adapter) {
super(adapter.getContext(), null);
this.adapter = adapter;
}
@Override
protected void openMedia(long accountId, long extraId, boolean sensitive, String link, int start, int end) {
final ParcelableStatus status = adapter.getStatus((int) extraId);
final ParcelableMedia current = StatusLinkClickHandler.findByLink(status.media, link);
Utils.openMedia(context, status, current);
}
}
} }

View File

@ -28,11 +28,10 @@ import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.util.MediaLoaderWrapper; import org.mariotaku.twidere.util.MediaLoaderWrapper;
import org.mariotaku.twidere.util.OnLinkClickHandler; import org.mariotaku.twidere.util.OnLinkClickHandler;
import org.mariotaku.twidere.util.TwidereLinkify; import org.mariotaku.twidere.util.TwidereLinkify;
import org.mariotaku.twidere.util.Utils;
import java.util.Collection; import java.util.Collection;
import static org.mariotaku.twidere.util.Utils.getLinkHighlightOptionInt;
public class BaseArrayAdapter<T> extends ArrayAdapter<T> implements IBaseAdapter, OnSharedPreferenceChangeListener { public class BaseArrayAdapter<T> extends ArrayAdapter<T> implements IBaseAdapter, OnSharedPreferenceChangeListener {
private final TwidereLinkify mLinkify; private final TwidereLinkify mLinkify;
@ -114,7 +113,7 @@ public class BaseArrayAdapter<T> extends ArrayAdapter<T> implements IBaseAdapter
@Override @Override
public final void setLinkHighlightOption(final String option) { public final void setLinkHighlightOption(final String option) {
final int optionInt = getLinkHighlightOptionInt(option); final int optionInt = Utils.getLinkHighlightingStyleInt(option);
mLinkify.setHighlightOption(optionInt); mLinkify.setHighlightOption(optionInt);
if (optionInt == mLinkHighlightOption) return; if (optionInt == mLinkHighlightOption) return;
mLinkHighlightOption = optionInt; mLinkHighlightOption = optionInt;

View File

@ -30,8 +30,7 @@ import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.util.MediaLoaderWrapper; import org.mariotaku.twidere.util.MediaLoaderWrapper;
import org.mariotaku.twidere.util.OnLinkClickHandler; import org.mariotaku.twidere.util.OnLinkClickHandler;
import org.mariotaku.twidere.util.TwidereLinkify; import org.mariotaku.twidere.util.TwidereLinkify;
import org.mariotaku.twidere.util.Utils;
import static org.mariotaku.twidere.util.Utils.getLinkHighlightOptionInt;
public class BaseCursorAdapter extends SimpleCursorAdapter implements IBaseAdapter, OnSharedPreferenceChangeListener { public class BaseCursorAdapter extends SimpleCursorAdapter implements IBaseAdapter, OnSharedPreferenceChangeListener {
@ -118,7 +117,7 @@ public class BaseCursorAdapter extends SimpleCursorAdapter implements IBaseAdapt
@Override @Override
public final void setLinkHighlightOption(final String option) { public final void setLinkHighlightOption(final String option) {
final int option_int = getLinkHighlightOptionInt(option); final int option_int = Utils.getLinkHighlightingStyleInt(option);
if (option_int == mLinkHighlightOption) return; if (option_int == mLinkHighlightOption) return;
mLinkHighlightOption = option_int; mLinkHighlightOption = option_int;
mLinkify.setHighlightOption(option_int); mLinkify.setHighlightOption(option_int);

View File

@ -24,6 +24,7 @@ import android.content.Context;
import org.mariotaku.twidere.util.AsyncTwitterWrapper; import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.ImageLoadingHandler; import org.mariotaku.twidere.util.ImageLoadingHandler;
import org.mariotaku.twidere.util.MediaLoaderWrapper; import org.mariotaku.twidere.util.MediaLoaderWrapper;
import org.mariotaku.twidere.view.CardMediaContainer.PreviewStyle;
import org.mariotaku.twidere.view.ShapedImageView.ShapeStyle; import org.mariotaku.twidere.view.ShapedImageView.ShapeStyle;
/** /**
@ -41,6 +42,7 @@ public interface IContentCardAdapter extends IGapSupportedAdapter, ContentCardCl
@ShapeStyle @ShapeStyle
int getProfileImageStyle(); int getProfileImageStyle();
@PreviewStyle
int getMediaPreviewStyle(); int getMediaPreviewStyle();
AsyncTwitterWrapper getTwitterWrapper(); AsyncTwitterWrapper getTwitterWrapper();

View File

@ -1,6 +1,7 @@
package org.mariotaku.twidere.adapter.iface; package org.mariotaku.twidere.adapter.iface;
import org.mariotaku.twidere.model.ParcelableStatus; import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.util.TwidereLinkify;
import org.mariotaku.twidere.view.holder.StatusViewHolder.StatusClickListener; import org.mariotaku.twidere.view.holder.StatusViewHolder.StatusClickListener;
/** /**
@ -14,8 +15,12 @@ public interface IStatusesAdapter<Data> extends IContentCardAdapter, StatusClick
long getStatusId(int position); long getStatusId(int position);
TwidereLinkify getTwidereLinkify();
boolean isMediaPreviewEnabled(); boolean isMediaPreviewEnabled();
int getLinkHighlightingStyle();
boolean isNameFirst(); boolean isNameFirst();
void setData(Data data); void setData(Data data);

View File

@ -32,15 +32,11 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import org.mariotaku.twidere.R; import org.mariotaku.twidere.R;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.model.ParcelableStatus; import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.util.AsyncTwitterWrapper; import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.ImageLoadingHandler;
import org.mariotaku.twidere.util.MediaLoaderWrapper;
import org.mariotaku.twidere.util.SharedPreferencesWrapper;
import org.mariotaku.twidere.util.ThemeUtils; import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.holder.StatusViewHolder; import org.mariotaku.twidere.view.holder.StatusViewHolder;
import org.mariotaku.twidere.view.holder.StatusViewHolder.DummyStatusHolderAdapter;
import static org.mariotaku.twidere.util.Utils.isMyRetweet; import static org.mariotaku.twidere.util.Utils.isMyRetweet;
@ -81,19 +77,9 @@ public class RetweetQuoteDialogFragment extends BaseSupportDialogFragment implem
final Context wrapped = ThemeUtils.getDialogThemedContext(getActivity()); final Context wrapped = ThemeUtils.getDialogThemedContext(getActivity());
final AlertDialog.Builder builder = new AlertDialog.Builder(wrapped); final AlertDialog.Builder builder = new AlertDialog.Builder(wrapped);
final Context context = builder.getContext(); final Context context = builder.getContext();
final SharedPreferencesWrapper preferences = SharedPreferencesWrapper.getInstance(context,
SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
final MediaLoaderWrapper loader = TwidereApplication.getInstance(context).getMediaLoaderWrapper();
final ImageLoadingHandler handler = new ImageLoadingHandler(R.id.media_preview_progress);
final AsyncTwitterWrapper twitter = getTwitterWrapper();
final LayoutInflater inflater = LayoutInflater.from(context); final LayoutInflater inflater = LayoutInflater.from(context);
@SuppressLint("InflateParams") final View view = inflater.inflate(R.layout.dialog_scrollable_status, null); @SuppressLint("InflateParams") final View view = inflater.inflate(R.layout.dialog_scrollable_status, null);
final StatusViewHolder holder = new StatusViewHolder(view.findViewById(R.id.item_content)); final StatusViewHolder holder = new StatusViewHolder(new DummyStatusHolderAdapter(context), view.findViewById(R.id.item_content));
final int profileImageStyle = Utils.getProfileImageStyle(preferences.getString(KEY_PROFILE_IMAGE_STYLE, null));
final int mediaPreviewStyle = Utils.getMediaPreviewStyle(preferences.getString(KEY_MEDIA_PREVIEW_STYLE, null));
final boolean nameFirst = preferences.getBoolean(KEY_NAME_FIRST, true);
final boolean displayProfileImage = preferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE, true);
final boolean displayMediaPreview = preferences.getBoolean(KEY_MEDIA_PREVIEW, false);
final ParcelableStatus status = getStatus(); final ParcelableStatus status = getStatus();
builder.setView(view); builder.setView(view);
@ -102,8 +88,7 @@ public class RetweetQuoteDialogFragment extends BaseSupportDialogFragment implem
builder.setNeutralButton(R.string.quote, this); builder.setNeutralButton(R.string.quote, this);
builder.setNegativeButton(android.R.string.cancel, null); builder.setNegativeButton(android.R.string.cancel, null);
holder.displayStatus(context, loader, handler, twitter, displayProfileImage, displayMediaPreview, holder.displayStatus(status, null, false, true);
true, true, nameFirst, profileImageStyle, mediaPreviewStyle, status, null, true);
view.findViewById(R.id.item_menu).setVisibility(View.GONE); view.findViewById(R.id.item_menu).setVisibility(View.GONE);
view.findViewById(R.id.action_buttons).setVisibility(View.GONE); view.findViewById(R.id.action_buttons).setVisibility(View.GONE);

View File

@ -101,6 +101,7 @@ import org.mariotaku.twidere.util.SharedPreferencesWrapper;
import org.mariotaku.twidere.util.StatusLinkClickHandler; import org.mariotaku.twidere.util.StatusLinkClickHandler;
import org.mariotaku.twidere.util.ThemeUtils; import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.TwidereLinkify; import org.mariotaku.twidere.util.TwidereLinkify;
import org.mariotaku.twidere.util.TwidereLinkify.OnLinkClickListener;
import org.mariotaku.twidere.util.TwitterCardUtils; import org.mariotaku.twidere.util.TwitterCardUtils;
import org.mariotaku.twidere.util.UserColorNameUtils; import org.mariotaku.twidere.util.UserColorNameUtils;
import org.mariotaku.twidere.util.Utils; import org.mariotaku.twidere.util.Utils;
@ -348,7 +349,9 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
popupMenu.show(); popupMenu.show();
mPopupMenu = popupMenu; mPopupMenu = popupMenu;
mSelectedStatus = status; mSelectedStatus = status;
} @Override }
@Override
public Loader<SingleResponse<ParcelableStatus>> onCreateLoader(final int id, final Bundle args) { public Loader<SingleResponse<ParcelableStatus>> onCreateLoader(final int id, final Bundle args) {
final Bundle fragmentArgs = getArguments(); final Bundle fragmentArgs = getArguments();
final long accountId = fragmentArgs.getLong(EXTRA_ACCOUNT_ID, -1); final long accountId = fragmentArgs.getLong(EXTRA_ACCOUNT_ID, -1);
@ -383,7 +386,9 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
private ParcelableStatus getStatus() { private ParcelableStatus getStatus() {
return mStatusAdapter.getStatus(); return mStatusAdapter.getStatus();
} @Override }
@Override
public void onLoadFinished(final Loader<SingleResponse<ParcelableStatus>> loader, public void onLoadFinished(final Loader<SingleResponse<ParcelableStatus>> loader,
final SingleResponse<ParcelableStatus> data) { final SingleResponse<ParcelableStatus> data) {
if (data.hasData()) { if (data.hasData()) {
@ -580,7 +585,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
final StatusLinkClickHandler linkClickHandler = new StatusLinkClickHandler(context, null); final StatusLinkClickHandler linkClickHandler = new StatusLinkClickHandler(context, null);
linkClickHandler.setStatus(status); linkClickHandler.setStatus(status);
final TwidereLinkify linkify = new TwidereLinkify(linkClickHandler, VALUE_LINK_HIGHLIGHT_OPTION_CODE_BOTH, false); final TwidereLinkify linkify = new TwidereLinkify(linkClickHandler, VALUE_LINK_HIGHLIGHT_OPTION_CODE_BOTH, false);
linkify.applyAllLinks(textView, status.account_id, status.is_possibly_sensitive); linkify.applyAllLinks(textView, status.account_id, getAdapterPosition(), status.is_possibly_sensitive);
ThemeUtils.applyParagraphSpacing(textView, 1.1f); ThemeUtils.applyParagraphSpacing(textView, 1.1f);
final String timeString = formatToLongTimeString(context, status.timestamp); final String timeString = formatToLongTimeString(context, status.timestamp);
@ -851,12 +856,14 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
public SpaceViewHolder(View itemView) { public SpaceViewHolder(View itemView) {
super(itemView); super(itemView);
} }
} @Override }
@Override
public void onLoaderReset(final Loader<SingleResponse<ParcelableStatus>> loader) { public void onLoaderReset(final Loader<SingleResponse<ParcelableStatus>> loader) {
} }
private static class StatusAdapter extends Adapter<ViewHolder> implements IStatusesAdapter<List<ParcelableStatus>> { private static class StatusAdapter extends Adapter<ViewHolder> implements IStatusesAdapter<List<ParcelableStatus>>, OnLinkClickListener {
private static final int VIEW_TYPE_DETAIL_STATUS = 0; private static final int VIEW_TYPE_DETAIL_STATUS = 0;
private static final int VIEW_TYPE_LIST_STATUS = 1; private static final int VIEW_TYPE_LIST_STATUS = 1;
@ -869,6 +876,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
private final LayoutInflater mInflater; private final LayoutInflater mInflater;
private final MediaLoaderWrapper mImageLoader; private final MediaLoaderWrapper mImageLoader;
private final ImageLoadingHandler mImageLoadingHandler; private final ImageLoadingHandler mImageLoadingHandler;
private final TwidereLinkify mLinkify;
private final boolean mNameFirst; private final boolean mNameFirst;
private final int mCardLayoutResource; private final int mCardLayoutResource;
@ -876,6 +884,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
private final int mCardBackgroundColor; private final int mCardBackgroundColor;
private final boolean mIsCompact; private final boolean mIsCompact;
private final int mProfileImageStyle; private final int mProfileImageStyle;
private final int mMediaPreviewStyle;
private final boolean mDisplayMediaPreview; private final boolean mDisplayMediaPreview;
private final boolean mDisplayProfileImage; private final boolean mDisplayProfileImage;
@ -903,6 +912,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
mNameFirst = preferences.getBoolean(KEY_NAME_FIRST, true); mNameFirst = preferences.getBoolean(KEY_NAME_FIRST, true);
mTextSize = preferences.getInt(KEY_TEXT_SIZE, res.getInteger(R.integer.default_text_size)); mTextSize = preferences.getInt(KEY_TEXT_SIZE, res.getInteger(R.integer.default_text_size));
mProfileImageStyle = Utils.getProfileImageStyle(preferences.getString(KEY_PROFILE_IMAGE_STYLE, null)); mProfileImageStyle = Utils.getProfileImageStyle(preferences.getString(KEY_PROFILE_IMAGE_STYLE, null));
mMediaPreviewStyle = Utils.getMediaPreviewStyle(preferences.getString(KEY_MEDIA_PREVIEW_STYLE, null));
mIsCompact = compact; mIsCompact = compact;
mDisplayProfileImage = preferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE, true); mDisplayProfileImage = preferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE, true);
mDisplayMediaPreview = preferences.getBoolean(KEY_MEDIA_PREVIEW, false); mDisplayMediaPreview = preferences.getBoolean(KEY_MEDIA_PREVIEW, false);
@ -911,6 +921,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
} else { } else {
mCardLayoutResource = R.layout.card_item_status; mCardLayoutResource = R.layout.card_item_status;
} }
mLinkify = new TwidereLinkify(this);
} }
public void addConversation(ParcelableStatus status, int position) { public void addConversation(ParcelableStatus status, int position) {
@ -953,7 +964,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
@Override @Override
public int getMediaPreviewStyle() { public int getMediaPreviewStyle() {
return 0; return mMediaPreviewStyle;
} }
@Override @Override
@ -975,6 +986,11 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
return mLoadMoreSupported; return mLoadMoreSupported;
} }
@Override
public void onLinkClick(String link, String orig, long accountId, long extraId, int type, boolean sensitive, int start, int end) {
}
@Override @Override
public void setLoadMoreSupported(boolean supported) { public void setLoadMoreSupported(boolean supported) {
mLoadMoreSupported = supported; mLoadMoreSupported = supported;
@ -1016,11 +1032,21 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
return status != null ? status.hashCode() : position; return status != null ? status.hashCode() : position;
} }
@Override
public TwidereLinkify getTwidereLinkify() {
return mLinkify;
}
@Override @Override
public boolean isMediaPreviewEnabled() { public boolean isMediaPreviewEnabled() {
return mDisplayMediaPreview; return mDisplayMediaPreview;
} }
@Override
public int getLinkHighlightingStyle() {
return 0;
}
public boolean isNameFirst() { public boolean isNameFirst() {
return mNameFirst; return mNameFirst;
} }
@ -1322,10 +1348,4 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
} }
} }

View File

@ -24,7 +24,6 @@ import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor; import android.content.SharedPreferences.Editor;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;
import android.support.v4.app.LoaderManager.LoaderCallbacks; import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.AsyncTaskLoader; import android.support.v4.content.AsyncTaskLoader;
@ -37,15 +36,11 @@ import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import org.mariotaku.twidere.R; import org.mariotaku.twidere.R;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.model.ParcelableStatus; import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.model.SingleResponse; import org.mariotaku.twidere.model.SingleResponse;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.ImageLoadingHandler;
import org.mariotaku.twidere.util.MediaLoaderWrapper;
import org.mariotaku.twidere.util.SharedPreferencesWrapper;
import org.mariotaku.twidere.util.Utils; import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.holder.StatusViewHolder; import org.mariotaku.twidere.view.holder.StatusViewHolder;
import org.mariotaku.twidere.view.holder.StatusViewHolder.DummyStatusHolderAdapter;
import twitter4j.TranslationResult; import twitter4j.TranslationResult;
import twitter4j.Twitter; import twitter4j.Twitter;
@ -55,6 +50,8 @@ public class StatusTranslateDialogFragment extends BaseSupportDialogFragment imp
LoaderCallbacks<SingleResponse<TranslationResult>> { LoaderCallbacks<SingleResponse<TranslationResult>> {
private StatusViewHolder mHolder; private StatusViewHolder mHolder;
private DummyStatusHolderAdapter mAdapter;
private ProgressBar mProgressBar; private ProgressBar mProgressBar;
private TextView mMessageView; private TextView mMessageView;
private View mProgressContainer; private View mProgressContainer;
@ -72,6 +69,8 @@ public class StatusTranslateDialogFragment extends BaseSupportDialogFragment imp
dismiss(); dismiss();
return; return;
} }
mAdapter = new DummyStatusHolderAdapter(getActivity());
mHolder = new StatusViewHolder(mAdapter, mStatusContainer);
getLoaderManager().initLoader(0, args, this); getLoaderManager().initLoader(0, args, this);
} }
@ -93,7 +92,6 @@ public class StatusTranslateDialogFragment extends BaseSupportDialogFragment imp
mProgressBar = (ProgressBar) mProgressContainer.findViewById(android.R.id.progress); mProgressBar = (ProgressBar) mProgressContainer.findViewById(android.R.id.progress);
mMessageView = (TextView) mProgressContainer.findViewById(android.R.id.message); mMessageView = (TextView) mProgressContainer.findViewById(android.R.id.message);
mStatusContainer = view.findViewById(R.id.status_container); mStatusContainer = view.findViewById(R.id.status_container);
mHolder = new StatusViewHolder(mStatusContainer);
} }
@Override @Override
@ -126,21 +124,7 @@ public class StatusTranslateDialogFragment extends BaseSupportDialogFragment imp
private void displayTranslatedStatus(final ParcelableStatus status, final TranslationResult translated) { private void displayTranslatedStatus(final ParcelableStatus status, final TranslationResult translated) {
if (status == null || translated == null) return; if (status == null || translated == null) return;
final FragmentActivity activity = getActivity(); mHolder.displayStatus(status, null, false, true);
final TwidereApplication application = getApplication();
final MediaLoaderWrapper loader = application.getMediaLoaderWrapper();
final ImageLoadingHandler handler = new ImageLoadingHandler(R.id.media_preview_progress);
final AsyncTwitterWrapper twitter = getTwitterWrapper();
final SharedPreferencesWrapper preferences = SharedPreferencesWrapper.getInstance(activity,
SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
final int profileImageStyle = Utils.getProfileImageStyle(preferences.getString(KEY_PROFILE_IMAGE_STYLE, null));
final int mediaPreviewStyle = Utils.getMediaPreviewStyle(preferences.getString(KEY_MEDIA_PREVIEW_STYLE, null));
final boolean nameFirst = preferences.getBoolean(KEY_NAME_FIRST, true);
final boolean displayProfileImage = preferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE, true);
final boolean displayMediaPreview = preferences.getBoolean(KEY_MEDIA_PREVIEW, false);
mHolder.displayStatus(activity, loader, handler, twitter, displayProfileImage, displayMediaPreview,
true, true, nameFirst, profileImageStyle, mediaPreviewStyle, status, null, true);
mStatusContainer.findViewById(R.id.item_menu).setVisibility(View.GONE); mStatusContainer.findViewById(R.id.item_menu).setVisibility(View.GONE);
mStatusContainer.findViewById(R.id.action_buttons).setVisibility(View.GONE); mStatusContainer.findViewById(R.id.action_buttons).setVisibility(View.GONE);

View File

@ -1052,7 +1052,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
} }
@Override @Override
public void onLinkClick(final String link, final String orig, final long account_id, final int type, public void onLinkClick(final String link, final String orig, final long accountId, long extraId, final int type,
final boolean sensitive, int start, int end) { final boolean sensitive, int start, int end) {
final ParcelableUser user = getUser(); final ParcelableUser user = getUser();
if (user == null) return; if (user == null) return;
@ -1085,7 +1085,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
break; break;
} }
case TwidereLinkify.LINK_TYPE_STATUS: { case TwidereLinkify.LINK_TYPE_STATUS: {
openStatus(getActivity(), account_id, parseLong(link)); openStatus(getActivity(), accountId, parseLong(link));
break; break;
} }
} }
@ -1278,8 +1278,8 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
final Context context = getActivity(); final Context context = getActivity();
final Bundle args = getArguments(), tabArgs = new Bundle(); final Bundle args = getArguments(), tabArgs = new Bundle();
final long accountId; final long accountId;
if (args.containsKey(EXTRA_USER)) {
final ParcelableUser user = args.getParcelable(EXTRA_USER); final ParcelableUser user = args.getParcelable(EXTRA_USER);
if (user != null) {
tabArgs.putLong(EXTRA_ACCOUNT_ID, accountId = user.account_id); tabArgs.putLong(EXTRA_ACCOUNT_ID, accountId = user.account_id);
tabArgs.putLong(EXTRA_USER_ID, user.id); tabArgs.putLong(EXTRA_USER_ID, user.id);
tabArgs.putString(EXTRA_SCREEN_NAME, user.screen_name); tabArgs.putString(EXTRA_SCREEN_NAME, user.screen_name);

View File

@ -35,14 +35,15 @@ import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.ImageLoadingHandler; import org.mariotaku.twidere.util.ImageLoadingHandler;
import org.mariotaku.twidere.util.MediaLoaderWrapper; import org.mariotaku.twidere.util.MediaLoaderWrapper;
import org.mariotaku.twidere.util.SharedPreferencesWrapper; import org.mariotaku.twidere.util.SharedPreferencesWrapper;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.holder.StatusViewHolder; import org.mariotaku.twidere.view.holder.StatusViewHolder;
import org.mariotaku.twidere.view.holder.StatusViewHolder.DummyStatusHolderAdapter;
/** /**
* Created by mariotaku on 15/3/17. * Created by mariotaku on 15/3/17.
*/ */
public class ViewStatusDialogFragment extends BaseSupportDialogFragment { public class ViewStatusDialogFragment extends BaseSupportDialogFragment {
private DummyStatusHolderAdapter mAdapter;
private StatusViewHolder mHolder; private StatusViewHolder mHolder;
private View mStatusContainer; private View mStatusContainer;
@ -59,7 +60,6 @@ public class ViewStatusDialogFragment extends BaseSupportDialogFragment {
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
mStatusContainer = view.findViewById(R.id.status_container); mStatusContainer = view.findViewById(R.id.status_container);
mHolder = new StatusViewHolder(view);
} }
@Override @Override
@ -70,27 +70,22 @@ public class ViewStatusDialogFragment extends BaseSupportDialogFragment {
dismiss(); dismiss();
return; return;
} }
final TwidereApplication application = getApplication(); final View view = getView();
if (view == null) throw new AssertionError();
final FragmentActivity activity = getActivity(); final FragmentActivity activity = getActivity();
mAdapter = new DummyStatusHolderAdapter(activity);
mHolder = new StatusViewHolder(mAdapter, getView());
final TwidereApplication application = getApplication();
final MediaLoaderWrapper loader = application.getMediaLoaderWrapper(); final MediaLoaderWrapper loader = application.getMediaLoaderWrapper();
final ImageLoadingHandler handler = new ImageLoadingHandler(R.id.media_preview_progress); final ImageLoadingHandler handler = new ImageLoadingHandler(R.id.media_preview_progress);
final AsyncTwitterWrapper twitter = getTwitterWrapper(); final AsyncTwitterWrapper twitter = getTwitterWrapper();
final SharedPreferencesWrapper preferences = SharedPreferencesWrapper.getInstance(activity, final SharedPreferencesWrapper preferences = SharedPreferencesWrapper.getInstance(activity,
SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE, SharedPreferenceConstants.class); SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE, SharedPreferenceConstants.class);
final ParcelableStatus status = args.getParcelable(EXTRA_STATUS); final ParcelableStatus status = args.getParcelable(EXTRA_STATUS);
final int profileImageStyle = Utils.getProfileImageStyle(preferences.getString(KEY_PROFILE_IMAGE_STYLE, null));
final int mediaPreviewStyle = Utils.getMediaPreviewStyle(preferences.getString(KEY_MEDIA_PREVIEW_STYLE, null));
final boolean nameFirst = preferences.getBoolean(KEY_NAME_FIRST, true);
final boolean displayExtraType = args.getBoolean(EXTRA_SHOW_EXTRA_TYPE, true);
final boolean displayProfileImage = preferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE);
final boolean displayMediaPreview;
if (args.containsKey(EXTRA_SHOW_MEDIA_PREVIEW)) { if (args.containsKey(EXTRA_SHOW_MEDIA_PREVIEW)) {
displayMediaPreview = args.getBoolean(EXTRA_SHOW_MEDIA_PREVIEW); mAdapter.setMediaPreviewEnabled(args.getBoolean(EXTRA_SHOW_MEDIA_PREVIEW));
} else {
displayMediaPreview = preferences.getBoolean(KEY_MEDIA_PREVIEW, false);
} }
mHolder.displayStatus(activity, loader, handler, twitter, displayProfileImage, displayMediaPreview, mHolder.displayStatus(status, null, false, true);
true, true, nameFirst, profileImageStyle, mediaPreviewStyle, status, null, displayExtraType);
mStatusContainer.findViewById(R.id.item_menu).setVisibility(View.GONE); mStatusContainer.findViewById(R.id.item_menu).setVisibility(View.GONE);
mStatusContainer.findViewById(R.id.action_buttons).setVisibility(View.GONE); mStatusContainer.findViewById(R.id.action_buttons).setVisibility(View.GONE);
} }

View File

@ -32,9 +32,9 @@ import android.view.ViewGroup;
import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R; import org.mariotaku.twidere.R;
import org.mariotaku.twidere.util.TwidereLinkify; import org.mariotaku.twidere.util.TwidereLinkify;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.holder.StatusViewHolder; import org.mariotaku.twidere.view.holder.StatusViewHolder;
import org.mariotaku.twidere.view.holder.StatusViewHolder.DummyStatusHolderAdapter;
import static org.mariotaku.twidere.util.Utils.getLinkHighlightOptionInt;
public class CardPreviewPreference extends Preference implements Constants, OnSharedPreferenceChangeListener { public class CardPreviewPreference extends Preference implements Constants, OnSharedPreferenceChangeListener {
@ -43,6 +43,7 @@ public class CardPreviewPreference extends Preference implements Constants, OnSh
private final TwidereLinkify mLinkify; private final TwidereLinkify mLinkify;
private StatusViewHolder mHolder; private StatusViewHolder mHolder;
private boolean mCompactModeChanged; private boolean mCompactModeChanged;
private DummyStatusHolderAdapter mAdapter;
public CardPreviewPreference(final Context context) { public CardPreviewPreference(final Context context) {
this(context, null); this(context, null);
@ -58,6 +59,7 @@ public class CardPreviewPreference extends Preference implements Constants, OnSh
mLinkify = new TwidereLinkify(null); mLinkify = new TwidereLinkify(null);
mPreferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); mPreferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
mPreferences.registerOnSharedPreferenceChangeListener(this); mPreferences.registerOnSharedPreferenceChangeListener(this);
mAdapter = new DummyStatusHolderAdapter(context);
} }
@Override @Override
@ -80,8 +82,8 @@ public class CardPreviewPreference extends Preference implements Constants, OnSh
if (mPreferences == null) return; if (mPreferences == null) return;
mCompactModeChanged = false; mCompactModeChanged = false;
final Context context = getContext(); final Context context = getContext();
final int highlightOption = getLinkHighlightOptionInt(context); final int highlightOption = Utils.getLinkHighlightingStyle(context);
mHolder = new StatusViewHolder(view); mHolder = new StatusViewHolder(mAdapter, view);
mHolder.displaySampleStatus(); mHolder.displaySampleStatus();
mLinkify.setHighlightOption(highlightOption); mLinkify.setHighlightOption(highlightOption);
super.onBindView(view); super.onBindView(view);

View File

@ -59,7 +59,7 @@ public class LinkHighlightPreference extends AutoInvalidateListPreference implem
super.onBindView(view); super.onBindView(view);
final TextView summary = (TextView) view.findViewById(android.R.id.summary); final TextView summary = (TextView) view.findViewById(android.R.id.summary);
summary.setVisibility(View.VISIBLE); summary.setVisibility(View.VISIBLE);
summary.setText(getStyledEntry(Utils.getLinkHighlightOptionInt(getValue()), getEntry())); summary.setText(getStyledEntry(Utils.getLinkHighlightingStyleInt(getValue()), getEntry()));
} }
private static CharSequence getStyledEntry(final int option, final CharSequence entry) { private static CharSequence getStyledEntry(final int option, final CharSequence entry) {

View File

@ -31,18 +31,20 @@ public class TwidereURLSpan extends URLSpan implements Constants {
private final int type, highlightStyle; private final int type, highlightStyle;
private final long accountId; private final long accountId;
private final long extraId;
private final String url, orig; private final String url, orig;
private final boolean sensitive; private final boolean sensitive;
private final OnLinkClickListener listener; private final OnLinkClickListener listener;
private final int start, end; private final int start, end;
public TwidereURLSpan(final String url, final String orig, final long accountId, final int type, public TwidereURLSpan(final String url, final String orig, final long accountId, final long extraId,
final boolean sensitive, final int highlightStyle, int start, int end, final int type, final boolean sensitive, final int highlightStyle, int start, int end,
final OnLinkClickListener listener) { final OnLinkClickListener listener) {
super(url); super(url);
this.url = url; this.url = url;
this.orig = orig; this.orig = orig;
this.accountId = accountId; this.accountId = accountId;
this.extraId = extraId;
this.type = type; this.type = type;
this.sensitive = sensitive; this.sensitive = sensitive;
this.highlightStyle = highlightStyle; this.highlightStyle = highlightStyle;
@ -54,7 +56,7 @@ public class TwidereURLSpan extends URLSpan implements Constants {
@Override @Override
public void onClick(@NonNull final View widget) { public void onClick(@NonNull final View widget) {
if (listener != null) { if (listener != null) {
listener.onLinkClick(url, orig, accountId, type, sensitive, start, end); listener.onLinkClick(url, orig, accountId, extraId, type, sensitive, start, end);
} }
} }

View File

@ -52,29 +52,29 @@ public class OnLinkClickHandler implements OnLinkClickListener, Constants {
} }
@Override @Override
public void onLinkClick(final String link, final String orig, final long account_id, final int type, public void onLinkClick(final String link, final String orig, final long accountId, long extraId, final int type,
final boolean sensitive, int start, int end) { final boolean sensitive, int start, int end) {
if (manager != null && manager.isActive()) return; if (manager != null && manager.isActive()) return;
if (!isPrivateData()) { if (!isPrivateData()) {
// UCD // UCD
ProfilingUtil.profile(context, account_id, "Click, " + link + ", " + type); ProfilingUtil.profile(context, accountId, "Click, " + link + ", " + type);
//spice //spice
SpiceProfilingUtil.profile(context, account_id, account_id + ",Visit," + link + "," + TypeMappingUtil.getLinkType(type)); SpiceProfilingUtil.profile(context, accountId, accountId + ",Visit," + link + "," + TypeMappingUtil.getLinkType(type));
//end //end
} }
switch (type) { switch (type) {
case TwidereLinkify.LINK_TYPE_MENTION: { case TwidereLinkify.LINK_TYPE_MENTION: {
openUserProfile(context, account_id, -1, link, null); openUserProfile(context, accountId, -1, link, null);
break; break;
} }
case TwidereLinkify.LINK_TYPE_HASHTAG: { case TwidereLinkify.LINK_TYPE_HASHTAG: {
openTweetSearch(context, account_id, "#" + link); openTweetSearch(context, accountId, "#" + link);
break; break;
} }
case TwidereLinkify.LINK_TYPE_LINK: { case TwidereLinkify.LINK_TYPE_LINK: {
if (MediaPreviewUtils.isLinkSupported(link)) { if (MediaPreviewUtils.isLinkSupported(link)) {
openMedia(account_id, sensitive, link, start, end); openMedia(accountId, extraId, sensitive, link, start, end);
} else { } else {
openLink(link); openLink(link);
} }
@ -85,19 +85,19 @@ public class OnLinkClickHandler implements OnLinkClickListener, Constants {
if (mentionList.length != 2) { if (mentionList.length != 2) {
break; break;
} }
openUserListDetails(context, account_id, -1, -1, mentionList[0], mentionList[1]); openUserListDetails(context, accountId, -1, -1, mentionList[0], mentionList[1]);
break; break;
} }
case TwidereLinkify.LINK_TYPE_CASHTAG: { case TwidereLinkify.LINK_TYPE_CASHTAG: {
openTweetSearch(context, account_id, link); openTweetSearch(context, accountId, link);
break; break;
} }
case TwidereLinkify.LINK_TYPE_USER_ID: { case TwidereLinkify.LINK_TYPE_USER_ID: {
openUserProfile(context, account_id, ParseUtils.parseLong(link), null, null); openUserProfile(context, accountId, ParseUtils.parseLong(link), null, null);
break; break;
} }
case TwidereLinkify.LINK_TYPE_STATUS: { case TwidereLinkify.LINK_TYPE_STATUS: {
openStatus(context, account_id, ParseUtils.parseLong(link)); openStatus(context, accountId, ParseUtils.parseLong(link));
break; break;
} }
} }
@ -107,9 +107,9 @@ public class OnLinkClickHandler implements OnLinkClickListener, Constants {
return false; return false;
} }
protected void openMedia(long account_id, boolean sensitive, String link, int start, int end) { protected void openMedia(long accountId, long extraId, boolean sensitive, String link, int start, int end) {
final ParcelableMedia[] media = {ParcelableMedia.newImage(link, link)}; final ParcelableMedia[] media = {ParcelableMedia.newImage(link, link)};
Utils.openMedia(context, account_id, sensitive, null, media); Utils.openMedia(context, accountId, sensitive, null, media);
} }
protected void openLink(final String link) { protected void openLink(final String link) {

View File

@ -32,13 +32,13 @@ public class StatusLinkClickHandler extends OnLinkClickHandler {
private ParcelableStatus mStatus; private ParcelableStatus mStatus;
@Override @Override
protected void openMedia(long account_id, boolean sensitive, String link, int start, int end) { protected void openMedia(long accountId, long extraId, boolean sensitive, String link, int start, int end) {
final ParcelableStatus status = mStatus; final ParcelableStatus status = mStatus;
final ParcelableMedia current = findByLink(status.media, link); final ParcelableMedia current = findByLink(status.media, link);
Utils.openMedia(context, status, current); Utils.openMedia(context, status, current);
} }
private ParcelableMedia findByLink(ParcelableMedia[] media, String link) { public static ParcelableMedia findByLink(ParcelableMedia[] media, String link) {
if (link == null || media == null) return null; if (link == null || media == null) return null;
for (ParcelableMedia mediaItem : media) { for (ParcelableMedia mediaItem : media) {
if (link.equals(mediaItem.media_url) || link.equals(mediaItem.page_url)) if (link.equals(mediaItem.media_url) || link.equals(mediaItem.page_url))

View File

@ -19,6 +19,7 @@
package org.mariotaku.twidere.util; package org.mariotaku.twidere.util;
import android.support.annotation.IntDef;
import android.text.Spannable; import android.text.Spannable;
import android.text.SpannableString; import android.text.SpannableString;
import android.text.Spanned; import android.text.Spanned;
@ -34,6 +35,8 @@ import com.twitter.Regex;
import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.text.TwidereURLSpan; import org.mariotaku.twidere.text.TwidereURLSpan;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List; import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -117,16 +120,20 @@ public final class TwidereLinkify implements Constants {
setHighlightOption(highlightOption); setHighlightOption(highlightOption);
} }
public final void applyAllLinks(final TextView view, final long account_id, final boolean sensitive) { public final void applyAllLinks(final TextView view, final long accountId, final long extraId, final boolean sensitive) {
applyAllLinks(view, account_id, sensitive, mOnLinkClickListener, mHighlightOption); applyAllLinks(view, accountId, extraId, sensitive, mOnLinkClickListener, mHighlightOption);
} }
public final void applyAllLinks(final TextView view, final long account_id, final boolean sensitive, public final void applyAllLinks(final TextView view, final long accountId, final boolean sensitive) {
final OnLinkClickListener listener, final int highlightOption) { applyAllLinks(view, accountId, -1, sensitive, mOnLinkClickListener, mHighlightOption);
}
public final void applyAllLinks(final TextView view, final long accountId, final long extraId,
final boolean sensitive, final OnLinkClickListener listener, final int highlightOption) {
view.setMovementMethod(LinkMovementMethod.getInstance()); view.setMovementMethod(LinkMovementMethod.getInstance());
final SpannableString string = SpannableString.valueOf(view.getText()); final SpannableString string = SpannableString.valueOf(view.getText());
for (final int type : ALL_LINK_TYPES) { for (final int type : ALL_LINK_TYPES) {
addLinks(string, account_id, type, sensitive, listener, highlightOption); addLinks(string, accountId, extraId, type, sensitive, listener, highlightOption);
} }
view.setText(string); view.setText(string);
if (mAddMovementMethod) { if (mAddMovementMethod) {
@ -134,13 +141,13 @@ public final class TwidereLinkify implements Constants {
} }
} }
public final void applyUserProfileLink(final TextView view, final long accountId, final long userId, public final void applyUserProfileLink(final TextView view, final long accountId, final long extraId,
final String screenName) { final long userId, final String screenName) {
applyUserProfileLink(view, accountId, userId, screenName, mOnLinkClickListener); applyUserProfileLink(view, accountId, extraId, userId, screenName, mOnLinkClickListener);
} }
public final void applyUserProfileLink(final TextView view, final long accountId, final long userId, public final void applyUserProfileLink(final TextView view, final long accountId, final long extraId,
final String screenName, final OnLinkClickListener listener) { final long userId, final String screenName, final OnLinkClickListener listener) {
view.setMovementMethod(LinkMovementMethod.getInstance()); view.setMovementMethod(LinkMovementMethod.getInstance());
final SpannableString string = SpannableString.valueOf(view.getText()); final SpannableString string = SpannableString.valueOf(view.getText());
final URLSpan[] spans = string.getSpans(0, string.length(), URLSpan.class); final URLSpan[] spans = string.getSpans(0, string.length(), URLSpan.class);
@ -148,10 +155,11 @@ public final class TwidereLinkify implements Constants {
string.removeSpan(span); string.removeSpan(span);
} }
if (userId > 0) { if (userId > 0) {
applyLink(String.valueOf(userId), 0, string.length(), string, accountId, LINK_TYPE_USER_ID, false, applyLink(String.valueOf(userId), 0, string.length(), string, accountId, extraId,
listener); LINK_TYPE_USER_ID, false, listener);
} else if (screenName != null) { } else if (screenName != null) {
applyLink(screenName, 0, string.length(), string, accountId, LINK_TYPE_MENTION, false, listener); applyLink(screenName, 0, string.length(), string, accountId, extraId,
LINK_TYPE_MENTION, false, listener);
} }
view.setText(string); view.setText(string);
if (mAddMovementMethod) { if (mAddMovementMethod) {
@ -159,29 +167,38 @@ public final class TwidereLinkify implements Constants {
} }
} }
public void setHighlightOption(final int style) { public void setHighlightOption(@HighlightStyle final int style) {
mHighlightOption = style; mHighlightOption = style;
} }
private boolean addCashtagLinks(final Spannable spannable, final long account_id, @IntDef({VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE, VALUE_LINK_HIGHLIGHT_OPTION_CODE_HIGHLIGHT,
VALUE_LINK_HIGHLIGHT_OPTION_CODE_UNDERLINE, VALUE_LINK_HIGHLIGHT_OPTION_CODE_BOTH})
@Retention(RetentionPolicy.SOURCE)
public static @interface HighlightStyle {
}
private boolean addCashtagLinks(final Spannable spannable, final long accountId, final long extraId,
final OnLinkClickListener listener, final int highlightOption) { final OnLinkClickListener listener, final int highlightOption) {
boolean hasMatches = false; boolean hasMatches = false;
for (final Entity entity : mExtractor.extractCashtagsWithIndices(spannable.toString())) { for (final Entity entity : mExtractor.extractCashtagsWithIndices(spannable.toString())) {
final int start = entity.getStart(); final int start = entity.getStart();
final int end = entity.getEnd(); final int end = entity.getEnd();
applyLink(entity.getValue(), start, end, spannable, account_id, LINK_TYPE_CASHTAG, false, listener); applyLink(entity.getValue(), start, end, spannable, accountId, extraId, LINK_TYPE_CASHTAG,
false, listener);
hasMatches = true; hasMatches = true;
} }
return hasMatches; return hasMatches;
} }
private boolean addHashtagLinks(final Spannable spannable, final long account_id, private boolean addHashtagLinks(final Spannable spannable, final long accountId, final long extraId,
final OnLinkClickListener listener, final int highlightOption) { final OnLinkClickListener listener, final int highlightOption) {
boolean hasMatches = false; boolean hasMatches = false;
for (final Entity entity : mExtractor.extractHashtagsWithIndices(spannable.toString())) { for (final Entity entity : mExtractor.extractHashtagsWithIndices(spannable.toString())) {
final int start = entity.getStart(); final int start = entity.getStart();
final int end = entity.getEnd(); final int end = entity.getEnd();
applyLink(entity.getValue(), start, end, spannable, account_id, LINK_TYPE_HASHTAG, false, listener); applyLink(entity.getValue(), start, end, spannable, accountId, extraId, LINK_TYPE_HASHTAG,
false, listener);
hasMatches = true; hasMatches = true;
} }
return hasMatches; return hasMatches;
@ -196,15 +213,15 @@ public final class TwidereLinkify implements Constants {
* @param highlightOption * @param highlightOption
* @param listener * @param listener
*/ */
private void addLinks(final SpannableString string, final long accountId, final int type, private void addLinks(final SpannableString string, final long accountId, final long extraId, final int type,
final boolean sensitive, final OnLinkClickListener listener, final int highlightOption) { final boolean sensitive, final OnLinkClickListener listener, final int highlightOption) {
switch (type) { switch (type) {
case LINK_TYPE_MENTION: { case LINK_TYPE_MENTION: {
addMentionOrListLinks(string, accountId, listener); addMentionOrListLinks(string, accountId, extraId, listener);
break; break;
} }
case LINK_TYPE_HASHTAG: { case LINK_TYPE_HASHTAG: {
addHashtagLinks(string, accountId, listener, highlightOption); addHashtagLinks(string, accountId, extraId, listener, highlightOption);
break; break;
} }
case LINK_TYPE_LINK: { case LINK_TYPE_LINK: {
@ -216,7 +233,7 @@ public final class TwidereLinkify implements Constants {
continue; continue;
} }
string.removeSpan(span); string.removeSpan(span);
applyLink(span.getURL(), start, end, string, accountId, LINK_TYPE_LINK, sensitive, listener); applyLink(span.getURL(), start, end, string, accountId, extraId, LINK_TYPE_LINK, sensitive, listener);
} }
final List<Extractor.Entity> urls = mExtractor.extractURLsWithIndices(ParseUtils.parseString(string)); final List<Extractor.Entity> urls = mExtractor.extractURLsWithIndices(ParseUtils.parseString(string));
for (final Extractor.Entity entity : urls) { for (final Extractor.Entity entity : urls) {
@ -225,7 +242,7 @@ public final class TwidereLinkify implements Constants {
|| string.getSpans(start, end, URLSpan.class).length > 0) { || string.getSpans(start, end, URLSpan.class).length > 0) {
continue; continue;
} }
applyLink(entity.getValue(), start, end, string, accountId, LINK_TYPE_LINK, sensitive, listener); applyLink(entity.getValue(), start, end, string, accountId, extraId, LINK_TYPE_LINK, sensitive, listener);
} }
break; break;
} }
@ -238,13 +255,13 @@ public final class TwidereLinkify implements Constants {
final int end = string.getSpanEnd(span); final int end = string.getSpanEnd(span);
final String url = matcherGroup(matcher, GROUP_ID_TWITTER_STATUS_STATUS_ID); final String url = matcherGroup(matcher, GROUP_ID_TWITTER_STATUS_STATUS_ID);
string.removeSpan(span); string.removeSpan(span);
applyLink(url, start, end, string, accountId, LINK_TYPE_STATUS, sensitive, listener); applyLink(url, start, end, string, accountId, extraId, LINK_TYPE_STATUS, sensitive, listener);
} }
} }
break; break;
} }
case LINK_TYPE_CASHTAG: { case LINK_TYPE_CASHTAG: {
addCashtagLinks(string, accountId, listener, highlightOption); addCashtagLinks(string, accountId, extraId, listener, highlightOption);
break; break;
} }
default: { default: {
@ -255,7 +272,7 @@ public final class TwidereLinkify implements Constants {
} }
private boolean addMentionOrListLinks(final Spannable spannable, final long accountId, private boolean addMentionOrListLinks(final Spannable spannable, final long accountId,
final OnLinkClickListener listener) { final long extraId, final OnLinkClickListener listener) {
boolean hasMatches = false; boolean hasMatches = false;
// Extract lists from status text // Extract lists from status text
final Matcher matcher = Regex.VALID_MENTION_OR_LIST.matcher(spannable); final Matcher matcher = Regex.VALID_MENTION_OR_LIST.matcher(spannable);
@ -266,10 +283,10 @@ public final class TwidereLinkify implements Constants {
final int listEnd = matcherEnd(matcher, Regex.VALID_MENTION_OR_LIST_GROUP_LIST); final int listEnd = matcherEnd(matcher, Regex.VALID_MENTION_OR_LIST_GROUP_LIST);
final String username = matcherGroup(matcher, Regex.VALID_MENTION_OR_LIST_GROUP_USERNAME); final String username = matcherGroup(matcher, Regex.VALID_MENTION_OR_LIST_GROUP_USERNAME);
final String list = matcherGroup(matcher, Regex.VALID_MENTION_OR_LIST_GROUP_LIST); final String list = matcherGroup(matcher, Regex.VALID_MENTION_OR_LIST_GROUP_LIST);
applyLink(username, start, username_end, spannable, accountId, LINK_TYPE_MENTION, false, listener); applyLink(username, start, username_end, spannable, accountId, extraId, LINK_TYPE_MENTION, false, listener);
if (listStart >= 0 && listEnd >= 0) { if (listStart >= 0 && listEnd >= 0) {
applyLink(String.format("%s/%s", username, list.substring(list.startsWith("/") ? 1 : 0)), listStart, applyLink(String.format("%s/%s", username, list.substring(list.startsWith("/") ? 1 : 0)), listStart,
listEnd, spannable, accountId, LINK_TYPE_LIST, false, listener); listEnd, spannable, accountId, extraId, LINK_TYPE_LIST, false, listener);
} }
hasMatches = true; hasMatches = true;
} }
@ -283,8 +300,8 @@ public final class TwidereLinkify implements Constants {
final String screenName = matcherGroup(m, GROUP_ID_TWITTER_LIST_SCREEN_NAME); final String screenName = matcherGroup(m, GROUP_ID_TWITTER_LIST_SCREEN_NAME);
final String listName = matcherGroup(m, GROUP_ID_TWITTER_LIST_LIST_NAME); final String listName = matcherGroup(m, GROUP_ID_TWITTER_LIST_LIST_NAME);
spannable.removeSpan(span); spannable.removeSpan(span);
applyLink(screenName + "/" + listName, start, end, spannable, accountId, LINK_TYPE_LIST, false, applyLink(screenName + "/" + listName, start, end, spannable, accountId, extraId,
listener); LINK_TYPE_LIST, false, listener);
hasMatches = true; hasMatches = true;
} }
} }
@ -292,15 +309,15 @@ public final class TwidereLinkify implements Constants {
} }
private void applyLink(final String url, final int start, final int end, final Spannable text, private void applyLink(final String url, final int start, final int end, final Spannable text,
final long accountId, final int type, final boolean sensitive, final long accountId, final long extraId, final int type, final boolean sensitive,
final OnLinkClickListener listener) { final OnLinkClickListener listener) {
applyLink(url, null, start, end, text, accountId, type, sensitive, listener); applyLink(url, null, start, end, text, accountId, extraId, type, sensitive, listener);
} }
private void applyLink(final String url, final String orig, final int start, final int end, private void applyLink(final String url, final String orig, final int start, final int end,
final Spannable text, final long accountId, final int type, final boolean sensitive, final Spannable text, final long accountId, final long extraId, final int type, final boolean sensitive,
final OnLinkClickListener listener) { final OnLinkClickListener listener) {
final TwidereURLSpan span = new TwidereURLSpan(url, orig, accountId, type, sensitive, final TwidereURLSpan span = new TwidereURLSpan(url, orig, accountId, extraId, type, sensitive,
mHighlightOption, start, end, listener); mHighlightOption, start, end, listener);
text.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); text.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} }
@ -315,7 +332,7 @@ public final class TwidereLinkify implements Constants {
} }
public interface OnLinkClickListener { public interface OnLinkClickListener {
public void onLinkClick(String link, String orig, long account_id, int type, public void onLinkClick(String link, String orig, long accountId, long extraId, int type,
boolean sensitive, int start, int end); boolean sensitive, int start, int end);
} }
} }

View File

@ -208,10 +208,12 @@ import org.mariotaku.twidere.provider.TwidereDataStore.Statuses;
import org.mariotaku.twidere.provider.TwidereDataStore.Tabs; import org.mariotaku.twidere.provider.TwidereDataStore.Tabs;
import org.mariotaku.twidere.provider.TwidereDataStore.UnreadCounts; import org.mariotaku.twidere.provider.TwidereDataStore.UnreadCounts;
import org.mariotaku.twidere.service.RefreshService; import org.mariotaku.twidere.service.RefreshService;
import org.mariotaku.twidere.util.TwidereLinkify.HighlightStyle;
import org.mariotaku.twidere.util.content.ContentResolverUtils; import org.mariotaku.twidere.util.content.ContentResolverUtils;
import org.mariotaku.twidere.util.menu.TwidereMenuInfo; import org.mariotaku.twidere.util.menu.TwidereMenuInfo;
import org.mariotaku.twidere.util.net.OkHttpClientFactory; import org.mariotaku.twidere.util.net.OkHttpClientFactory;
import org.mariotaku.twidere.util.net.TwidereHostResolverFactory; import org.mariotaku.twidere.util.net.TwidereHostResolverFactory;
import org.mariotaku.twidere.view.CardMediaContainer.PreviewStyle;
import org.mariotaku.twidere.view.ShapedImageView; import org.mariotaku.twidere.view.ShapedImageView;
import org.mariotaku.twidere.view.ShapedImageView.ShapeStyle; import org.mariotaku.twidere.view.ShapedImageView.ShapeStyle;
@ -1887,17 +1889,19 @@ public final class Utils implements Constants, TwitterConstants {
return sb; return sb;
} }
public static String getLinkHighlightOption(final Context context) { public static String getLinkHighlightingStyleName(final Context context) {
if (context == null) return null; if (context == null) return null;
final SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE); final SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
return prefs.getString(KEY_LINK_HIGHLIGHT_OPTION, VALUE_LINK_HIGHLIGHT_OPTION_NONE); return prefs.getString(KEY_LINK_HIGHLIGHT_OPTION, VALUE_LINK_HIGHLIGHT_OPTION_NONE);
} }
public static int getLinkHighlightOptionInt(final Context context) { @HighlightStyle
return getLinkHighlightOptionInt(getLinkHighlightOption(context)); public static int getLinkHighlightingStyle(final Context context) {
return getLinkHighlightingStyleInt(getLinkHighlightingStyleName(context));
} }
public static int getLinkHighlightOptionInt(final String option) { @HighlightStyle
public static int getLinkHighlightingStyleInt(final String option) {
if (VALUE_LINK_HIGHLIGHT_OPTION_BOTH.equals(option)) if (VALUE_LINK_HIGHLIGHT_OPTION_BOTH.equals(option))
return VALUE_LINK_HIGHLIGHT_OPTION_CODE_BOTH; return VALUE_LINK_HIGHLIGHT_OPTION_CODE_BOTH;
else if (VALUE_LINK_HIGHLIGHT_OPTION_HIGHLIGHT.equals(option)) else if (VALUE_LINK_HIGHLIGHT_OPTION_HIGHLIGHT.equals(option))
@ -2100,6 +2104,7 @@ public final class Utils implements Constants, TwitterConstants {
return ShapedImageView.SHAPE_CIRCLE; return ShapedImageView.SHAPE_CIRCLE;
} }
@PreviewStyle
public static int getMediaPreviewStyle(String style) { public static int getMediaPreviewStyle(String style) {
if (VALUE_MEDIA_PREVIEW_STYLE_SCALE.equalsIgnoreCase(style)) { if (VALUE_MEDIA_PREVIEW_STYLE_SCALE.equalsIgnoreCase(style)) {
return VALUE_MEDIA_PREVIEW_STYLE_CODE_SCALE; return VALUE_MEDIA_PREVIEW_STYLE_CODE_SCALE;

View File

@ -21,6 +21,7 @@ package org.mariotaku.twidere.view;
import android.content.Context; import android.content.Context;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.util.AttributeSet; import android.util.AttributeSet;
@ -37,6 +38,9 @@ import org.mariotaku.twidere.util.ImageLoadingHandler;
import org.mariotaku.twidere.util.MediaLoaderWrapper; import org.mariotaku.twidere.util.MediaLoaderWrapper;
import org.mariotaku.twidere.util.Utils.OnMediaClickListener; import org.mariotaku.twidere.util.Utils.OnMediaClickListener;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/** /**
* Created by mariotaku on 14/12/17. * Created by mariotaku on 14/12/17.
*/ */
@ -287,4 +291,10 @@ public class CardMediaContainer extends ViewGroup implements Constants {
} }
} }
@IntDef({VALUE_MEDIA_PREVIEW_STYLE_CODE_SCALE, VALUE_MEDIA_PREVIEW_STYLE_CODE_CROP})
@Retention(RetentionPolicy.SOURCE)
public static @interface PreviewStyle {
}
} }

View File

@ -324,7 +324,9 @@ public class TabPagerIndicator extends RecyclerView implements PagerIndicator {
@Override @Override
public boolean onLongClick(View v) { public boolean onLongClick(View v) {
return indicator.dispatchTabLongClick(getAdapterPosition()); final int position = getAdapterPosition();
if (position == RecyclerView.NO_POSITION) return false;
return indicator.dispatchTabLongClick(position);
} }
public void setBadge(int count, boolean display) { public void setBadge(int count, boolean display) {

View File

@ -7,6 +7,9 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v7.widget.CardView; import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.text.Html;
import android.text.TextUtils;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.widget.ImageView; import android.widget.ImageView;
@ -16,6 +19,7 @@ import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R; import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.iface.ContentCardClickListener; import org.mariotaku.twidere.adapter.iface.ContentCardClickListener;
import org.mariotaku.twidere.adapter.iface.IStatusesAdapter; import org.mariotaku.twidere.adapter.iface.IStatusesAdapter;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.model.ParcelableLocation; import org.mariotaku.twidere.model.ParcelableLocation;
import org.mariotaku.twidere.model.ParcelableMedia; import org.mariotaku.twidere.model.ParcelableMedia;
import org.mariotaku.twidere.model.ParcelableStatus; import org.mariotaku.twidere.model.ParcelableStatus;
@ -23,7 +27,9 @@ import org.mariotaku.twidere.model.ParcelableStatus.CursorIndices;
import org.mariotaku.twidere.util.AsyncTwitterWrapper; import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.ImageLoadingHandler; import org.mariotaku.twidere.util.ImageLoadingHandler;
import org.mariotaku.twidere.util.MediaLoaderWrapper; import org.mariotaku.twidere.util.MediaLoaderWrapper;
import org.mariotaku.twidere.util.SharedPreferencesWrapper;
import org.mariotaku.twidere.util.SimpleValueSerializer; import org.mariotaku.twidere.util.SimpleValueSerializer;
import org.mariotaku.twidere.util.TwidereLinkify;
import org.mariotaku.twidere.util.TwitterCardUtils; import org.mariotaku.twidere.util.TwitterCardUtils;
import org.mariotaku.twidere.util.UserColorNameUtils; import org.mariotaku.twidere.util.UserColorNameUtils;
import org.mariotaku.twidere.util.Utils; import org.mariotaku.twidere.util.Utils;
@ -48,6 +54,7 @@ import static org.mariotaku.twidere.util.Utils.getUserTypeIconRes;
public class StatusViewHolder extends RecyclerView.ViewHolder implements Constants, OnClickListener, public class StatusViewHolder extends RecyclerView.ViewHolder implements Constants, OnClickListener,
OnMediaClickListener { OnMediaClickListener {
@NonNull
private final IStatusesAdapter<?> adapter; private final IStatusesAdapter<?> adapter;
private final ImageView replyRetweetIcon; private final ImageView replyRetweetIcon;
@ -64,12 +71,7 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements Constan
private StatusClickListener statusClickListener; private StatusClickListener statusClickListener;
public StatusViewHolder(@NonNull final IStatusesAdapter<?> adapter, @NonNull final View itemView) {
public StatusViewHolder(View itemView) {
this(null, itemView);
}
public StatusViewHolder(IStatusesAdapter<?> adapter, View itemView) {
super(itemView); super(itemView);
this.adapter = adapter; this.adapter = adapter;
itemContent = (IColorLabelView) itemView.findViewById(R.id.item_content); itemContent = (IColorLabelView) itemView.findViewById(R.id.item_content);
@ -102,23 +104,23 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements Constan
} }
public void displayStatus(final ParcelableStatus status, final boolean displayInReplyTo) { public void displayStatus(final ParcelableStatus status, final boolean displayInReplyTo) {
displayStatus(adapter.getContext(), adapter.getImageLoader(), displayStatus(status, null, displayInReplyTo, true);
adapter.getImageLoadingHandler(), adapter.getTwitterWrapper(),
adapter.isProfileImageEnabled(),
adapter.isMediaPreviewEnabled(), adapter.shouldShowAccountsColor(),
displayInReplyTo, adapter.isNameFirst(), adapter.getProfileImageStyle(),
adapter.getMediaPreviewStyle(), status, null, displayInReplyTo);
} }
public void displayStatus(@NonNull final Context context, public void displayStatus(@NonNull final ParcelableStatus status, @Nullable final TranslationResult translation,
@NonNull final MediaLoaderWrapper loader, final boolean displayInReplyTo, final boolean shouldDisplayExtraType) {
@NonNull final ImageLoadingHandler handler, final Context context = adapter.getContext();
@NonNull final AsyncTwitterWrapper twitter, final MediaLoaderWrapper loader = adapter.getImageLoader();
final boolean displayProfileImage, final boolean displayMediaPreview, final ImageLoadingHandler handler = adapter.getImageLoadingHandler();
final boolean displayAccountsColor, final boolean displayInReplyTo, final AsyncTwitterWrapper twitter = adapter.getTwitterWrapper();
final boolean nameFirst, final int profileImageStyle, final int mediaPreviewStyle, final TwidereLinkify linkify = adapter.getTwidereLinkify();
@NonNull final ParcelableStatus status, @Nullable final TranslationResult translation, final boolean displayProfileImage = adapter.isProfileImageEnabled();
boolean shouldDisplayExtraType) { final boolean displayMediaPreview = adapter.isMediaPreviewEnabled();
final boolean displayAccountsColor = adapter.shouldShowAccountsColor();
final boolean nameFirst = adapter.isNameFirst();
final int profileImageStyle = adapter.getProfileImageStyle();
final int mediaPreviewStyle = adapter.getMediaPreviewStyle();
final int linkHighlightingStyle = adapter.getLinkHighlightingStyle();
final ParcelableMedia[] media = status.media; final ParcelableMedia[] media = status.media;
replyRetweetIcon.setColorFilter(replyRetweetView.getCurrentTextColor(), Mode.SRC_ATOP); replyRetweetIcon.setColorFilter(replyRetweetView.getCurrentTextColor(), Mode.SRC_ATOP);
@ -189,8 +191,11 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements Constan
} }
if (translation != null) { if (translation != null) {
textView.setText(translation.getText()); textView.setText(translation.getText());
} else { } else if (linkHighlightingStyle == VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
textView.setText(status.text_unescaped); textView.setText(status.text_unescaped);
} else {
textView.setText(Html.fromHtml(status.text_html));
linkify.applyAllLinks(textView, status.account_id, getAdapterPosition(), status.is_possibly_sensitive);
} }
if (status.reply_count > 0) { if (status.reply_count > 0) {
@ -240,6 +245,7 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements Constan
final boolean displayInReplyTo) { final boolean displayInReplyTo) {
final MediaLoaderWrapper loader = adapter.getImageLoader(); final MediaLoaderWrapper loader = adapter.getImageLoader();
final AsyncTwitterWrapper twitter = adapter.getTwitterWrapper(); final AsyncTwitterWrapper twitter = adapter.getTwitterWrapper();
final TwidereLinkify linkify = adapter.getTwidereLinkify();
final Context context = adapter.getContext(); final Context context = adapter.getContext();
final boolean nameFirst = adapter.isNameFirst(); final boolean nameFirst = adapter.isNameFirst();
@ -328,7 +334,6 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements Constan
loader.cancelDisplayTask(profileImageView); loader.cancelDisplayTask(profileImageView);
} }
final String text_unescaped = cursor.getString(indices.text_unescaped);
if (adapter.isMediaPreviewEnabled()) { if (adapter.isMediaPreviewEnabled()) {
mediaPreviewContainer.setStyle(adapter.getMediaPreviewStyle()); mediaPreviewContainer.setStyle(adapter.getMediaPreviewStyle());
mediaPreviewContainer.setVisibility(media != null && media.length > 0 ? View.VISIBLE : View.GONE); mediaPreviewContainer.setVisibility(media != null && media.length > 0 ? View.VISIBLE : View.GONE);
@ -337,7 +342,13 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements Constan
} else { } else {
mediaPreviewContainer.setVisibility(View.GONE); mediaPreviewContainer.setVisibility(View.GONE);
} }
textView.setText(text_unescaped); if (adapter.getLinkHighlightingStyle() == VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
textView.setText(cursor.getString(indices.text_unescaped));
} else {
textView.setText(Html.fromHtml(cursor.getString(indices.text_html)));
linkify.applyAllLinks(textView, account_id, getAdapterPosition(),
cursor.getShort(indices.is_possibly_sensitive) == 1);
}
if (reply_count > 0) { if (reply_count > 0) {
replyCountView.setText(Utils.getLocalizedNumber(Locale.getDefault(), reply_count)); replyCountView.setText(Utils.getLocalizedNumber(Locale.getDefault(), reply_count));
@ -472,7 +483,7 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements Constan
extraTypeView.setImageResource(R.drawable.ic_action_gallery); extraTypeView.setImageResource(R.drawable.ic_action_gallery);
} }
extraTypeView.setVisibility(View.VISIBLE); extraTypeView.setVisibility(View.VISIBLE);
} else if (location != null && location.isValid()) { } else if (ParcelableLocation.isValidLocation(location) || !TextUtils.isEmpty(placeFullName)) {
extraTypeView.setImageResource(R.drawable.ic_action_location); extraTypeView.setImageResource(R.drawable.ic_action_location);
extraTypeView.setVisibility(View.VISIBLE); extraTypeView.setVisibility(View.VISIBLE);
} else { } else {
@ -497,4 +508,183 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements Constan
void onUserProfileClick(StatusViewHolder holder, int position); void onUserProfileClick(StatusViewHolder holder, int position);
} }
public static final class DummyStatusHolderAdapter implements IStatusesAdapter<Object> {
private final Context context;
private final MediaLoaderWrapper loader;
private final ImageLoadingHandler handler;
private final AsyncTwitterWrapper twitter;
private final TwidereLinkify linkify;
private final int profileImageStyle, mediaPreviewStyle;
private final boolean nameFirst;
private final boolean displayProfileImage;
private boolean displayMediaPreview;
public DummyStatusHolderAdapter(Context context) {
this.context = context;
final SharedPreferencesWrapper preferences = SharedPreferencesWrapper.getInstance(context,
SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
loader = TwidereApplication.getInstance(context).getMediaLoaderWrapper();
handler = new ImageLoadingHandler(R.id.media_preview_progress);
twitter = getTwitterWrapper();
linkify = new TwidereLinkify(null);
profileImageStyle = Utils.getProfileImageStyle(preferences.getString(KEY_PROFILE_IMAGE_STYLE, null));
mediaPreviewStyle = Utils.getMediaPreviewStyle(preferences.getString(KEY_MEDIA_PREVIEW_STYLE, null));
nameFirst = preferences.getBoolean(KEY_NAME_FIRST, true);
displayProfileImage = preferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE, true);
displayMediaPreview = preferences.getBoolean(KEY_MEDIA_PREVIEW, false);
}
@Override
public MediaLoaderWrapper getImageLoader() {
return loader;
}
@Override
public Context getContext() {
return context;
}
@Override
public ImageLoadingHandler getImageLoadingHandler() {
return handler;
}
@Override
public int getItemCount() {
return 0;
}
@Override
public int getProfileImageStyle() {
return profileImageStyle;
}
@Override
public int getMediaPreviewStyle() {
return mediaPreviewStyle;
}
@Override
public AsyncTwitterWrapper getTwitterWrapper() {
return twitter;
}
@Override
public float getTextSize() {
return 0;
}
@Override
public boolean isLoadMoreIndicatorVisible() {
return false;
}
@Override
public boolean isLoadMoreSupported() {
return false;
}
@Override
public boolean isProfileImageEnabled() {
return displayProfileImage;
}
@Override
public void onItemActionClick(ViewHolder holder, int id, int position) {
}
@Override
public void onItemMenuClick(ViewHolder holder, View menuView, int position) {
}
@Override
public void onStatusClick(StatusViewHolder holder, int position) {
}
@Override
public void onMediaClick(StatusViewHolder holder, ParcelableMedia media, int position) {
}
@Override
public void onUserProfileClick(StatusViewHolder holder, int position) {
}
@Override
public boolean isGapItem(int position) {
return false;
}
@Override
public void onGapClick(ViewHolder holder, int position) {
}
@Override
public void setLoadMoreSupported(boolean supported) {
}
@Override
public void setLoadMoreIndicatorVisible(boolean enabled) {
}
@Override
public ParcelableStatus getStatus(int position) {
return null;
}
@Override
public int getStatusesCount() {
return 0;
}
@Override
public long getStatusId(int position) {
return 0;
}
@Override
public TwidereLinkify getTwidereLinkify() {
return linkify;
}
@Override
public boolean isMediaPreviewEnabled() {
return displayMediaPreview;
}
@Override
public int getLinkHighlightingStyle() {
return 0;
}
@Override
public boolean isNameFirst() {
return nameFirst;
}
@Override
public void setData(Object o) {
}
public void setMediaPreviewEnabled(boolean enabled) {
displayMediaPreview = enabled;
}
@Override
public boolean shouldShowAccountsColor() {
return false;
}
}
} }