This commit is contained in:
Mariotaku Lee 2016-03-02 17:08:28 +08:00
parent 4eb2469cc5
commit c7654db62d
10 changed files with 45 additions and 24 deletions

View File

@ -281,6 +281,9 @@ public class Status extends TwitterResponseObject implements Comparable<Status>,
return entities.getUrls();
}
public Entities getEntities() {
return entities;
}
public UserMentionEntity[] getUserMentionEntities() {
if (entities == null) return null;

View File

@ -437,6 +437,9 @@ public class ParcelableStatus implements Parcelable, Comparable<ParcelableStatus
@JsonField(name = "external_url")
@ParcelableThisPlease
public String external_url;
@JsonField(name = "support_entities")
@ParcelableThisPlease
public boolean support_entities;
@Override
public int describeContents() {

View File

@ -38,7 +38,7 @@ public class TwidereDataUtils {
return "mention";
case TwidereLinkify.LINK_TYPE_CASHTAG:
return "cashTag";
case TwidereLinkify.LINK_TYPE_LINK:
case TwidereLinkify.LINK_TYPE_ENTITY_URL:
return "urlLink";
case TwidereLinkify.LINK_TYPE_LIST:
return "userList";

View File

@ -999,6 +999,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
profileContainer.drawEnd(DataStoreUtils.getAccountColor(context, status.account_id));
final int layoutPosition = getLayoutPosition();
final boolean skipLinksInText = status.extras != null && status.extras.support_entities;
if (status.is_quote && ArrayUtils.isEmpty(status.media)) {
quoteOriginalLink.setVisibility(View.VISIBLE);
@ -1013,7 +1014,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
status.text_unescaped);
if (quotedText instanceof Spanned) {
quotedTextView.setText(linkify.applyAllLinks(quotedText, status.account_id,
layoutPosition, status.is_possibly_sensitive));
layoutPosition, status.is_possibly_sensitive, skipLinksInText));
}
quoteIndicator.setColor(manager.getUserColor(status.user_id, false));
@ -1067,7 +1068,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
status.text_unescaped);
if (text instanceof Spanned) {
textView.setText(linkify.applyAllLinks(text, status.account_id, layoutPosition,
status.is_possibly_sensitive));
status.is_possibly_sensitive, skipLinksInText));
}
final ParcelableLocation location;

View File

@ -533,7 +533,8 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
mDescriptionContainer.setVisibility(TextUtils.isEmpty(user.description_html) ? View.GONE : View.VISIBLE);
final TwidereLinkify linkify = new TwidereLinkify(this);
mDescriptionView.setText(linkify.applyAllLinks(user.description_html != null ?
HtmlSpanBuilder.fromHtml(user.description_html) : user.description_plain, user.account_id, false));
HtmlSpanBuilder.fromHtml(user.description_html) : user.description_plain,
user.account_id, false, false));
mLocationContainer.setVisibility(TextUtils.isEmpty(user.location) ? View.GONE : View.VISIBLE);
mLocationView.setText(user.location);
mURLContainer.setVisibility(TextUtils.isEmpty(user.url) && TextUtils.isEmpty(user.url_expanded) ? View.GONE : View.VISIBLE);
@ -1310,7 +1311,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
Utils.openTweetSearch(getActivity(), user.account_id, "#" + link);
break;
}
case TwidereLinkify.LINK_TYPE_LINK: {
case TwidereLinkify.LINK_TYPE_ENTITY_URL: {
final Uri uri = Uri.parse(link);
final Intent intent;
if (uri.getScheme() != null) {

View File

@ -39,6 +39,7 @@ public class ParcelableStatusUtils {
result.timestamp = getTime(orig.getCreatedAt());
result.extras = new ParcelableStatus.Extras();
result.extras.external_url = orig.getExternalUrl();
result.extras.support_entities = orig.getEntities() != null;
final Status retweetedStatus = orig.getRetweetedStatus();
final User retweetUser = retweetedStatus != null ? orig.getUser() : null;

View File

@ -69,7 +69,7 @@ public class OnLinkClickHandler implements OnLinkClickListener, Constants {
Utils.openTweetSearch(context, accountId, "#" + link);
break;
}
case TwidereLinkify.LINK_TYPE_LINK: {
case TwidereLinkify.LINK_TYPE_ENTITY_URL: {
if (PreviewMediaExtractor.isSupported(link)) {
openMedia(accountId, extraId, sensitive, link, start, end);
} else {

View File

@ -61,14 +61,15 @@ public final class TwidereLinkify implements Constants {
public static final int LINK_TYPE_MENTION = 1;
public static final int LINK_TYPE_HASHTAG = 2;
public static final int LINK_TYPE_LINK = 4;
public static final int LINK_TYPE_ENTITY_URL = 4;
public static final int LINK_TYPE_LINK_IN_TEXT = 5;
public static final int LINK_TYPE_LIST = 6;
public static final int LINK_TYPE_CASHTAG = 7;
public static final int LINK_TYPE_USER_ID = 8;
public static final int LINK_TYPE_STATUS = 9;
public static final int[] ALL_LINK_TYPES = new int[]{LINK_TYPE_LINK, LINK_TYPE_MENTION, LINK_TYPE_HASHTAG,
LINK_TYPE_STATUS, LINK_TYPE_CASHTAG};
public static final int[] ALL_LINK_TYPES = new int[]{LINK_TYPE_ENTITY_URL, LINK_TYPE_LINK_IN_TEXT,
LINK_TYPE_MENTION, LINK_TYPE_HASHTAG, LINK_TYPE_STATUS, LINK_TYPE_CASHTAG};
public static final String AVAILABLE_URL_SCHEME_PREFIX = "(https?://)?";
@ -107,25 +108,31 @@ public final class TwidereLinkify implements Constants {
setHighlightOption(highlightOption);
}
public SpannableString applyAllLinks(@Nullable CharSequence text, final long accountId, final long extraId, final boolean sensitive) {
return applyAllLinks(text, mOnLinkClickListener, accountId, extraId, sensitive, mHighlightOption);
public SpannableString applyAllLinks(@Nullable CharSequence text, final long accountId,
final long extraId, final boolean sensitive,
final boolean skipLinksInText) {
return applyAllLinks(text, mOnLinkClickListener, accountId, extraId, sensitive,
mHighlightOption, skipLinksInText);
}
public SpannableString applyAllLinks(@Nullable CharSequence text, final long accountId, final boolean sensitive) {
return applyAllLinks(text, mOnLinkClickListener, accountId, -1, sensitive, mHighlightOption);
public SpannableString applyAllLinks(@Nullable CharSequence text, final long accountId,
final boolean sensitive, final boolean skipLinksInText) {
return applyAllLinks(text, mOnLinkClickListener, accountId, -1, sensitive, mHighlightOption, skipLinksInText);
}
public SpannableString applyAllLinks(@Nullable CharSequence text, final long accountId, final long extraId,
final boolean sensitive, final int highlightOption) {
return applyAllLinks(text, mOnLinkClickListener, accountId, extraId, sensitive, highlightOption);
public SpannableString applyAllLinks(@Nullable CharSequence text, final long accountId,
final long extraId, final boolean sensitive,
final int highlightOption, final boolean skipLinksInText) {
return applyAllLinks(text, mOnLinkClickListener, accountId, extraId, sensitive, highlightOption, skipLinksInText);
}
public SpannableString applyAllLinks(@Nullable final CharSequence text, final OnLinkClickListener listener,
final long accountId, final long extraId, final boolean sensitive,
final int highlightOption) {
final int highlightOption, boolean skipLinksInText) {
if (text == null) return null;
final SpannableString string = SpannableString.valueOf(text);
for (final int type : ALL_LINK_TYPES) {
if (type == LINK_TYPE_LINK_IN_TEXT && skipLinksInText) continue;
addLinks(string, accountId, extraId, type, sensitive, listener, highlightOption);
}
return string;
@ -202,7 +209,7 @@ public final class TwidereLinkify implements Constants {
addHashtagLinks(string, accountId, extraId, listener, highlightOption);
break;
}
case LINK_TYPE_LINK: {
case LINK_TYPE_ENTITY_URL: {
final URLSpan[] spans = string.getSpans(0, string.length(), URLSpan.class);
for (final URLSpan span : spans) {
final int start = string.getSpanStart(span);
@ -211,8 +218,11 @@ public final class TwidereLinkify implements Constants {
continue;
}
string.removeSpan(span);
applyLink(span.getURL(), start, end, string, accountId, extraId, LINK_TYPE_LINK, sensitive, highlightOption, listener);
applyLink(span.getURL(), start, end, string, accountId, extraId, LINK_TYPE_ENTITY_URL, sensitive, highlightOption, listener);
}
break;
}
case LINK_TYPE_LINK_IN_TEXT: {
final List<Extractor.Entity> urls = mExtractor.extractURLsWithIndices(ParseUtils.parseString(string));
for (final Extractor.Entity entity : urls) {
final int start = entity.getStart(), end = entity.getEnd();
@ -220,7 +230,7 @@ public final class TwidereLinkify implements Constants {
|| string.getSpans(start, end, URLSpan.class).length > 0) {
continue;
}
applyLink(entity.getValue(), start, end, string, accountId, extraId, LINK_TYPE_LINK, sensitive, highlightOption, listener);
applyLink(entity.getValue(), start, end, string, accountId, extraId, LINK_TYPE_ENTITY_URL, sensitive, highlightOption, listener);
}
break;
}

View File

@ -82,7 +82,8 @@ public class MessageViewHolder extends ViewHolder {
final ParcelableMedia[] media = JsonSerializer.parseArray(cursor.getString(indices.media),
ParcelableMedia.class);
final Spanned text = HtmlSpanBuilder.fromHtml(cursor.getString(indices.text_html));
textView.setText(linkify.applyAllLinks(text, accountId, false));
// Detect entity support
textView.setText(linkify.applyAllLinks(text, accountId, false, true));
time.setText(Utils.formatToLongTimeString(context, timestamp));
mediaContainer.setVisibility(media != null && media.length > 0 ? View.VISIBLE : View.GONE);
mediaContainer.displayMedia(media, loader, accountId, getLayoutPosition(), true,

View File

@ -136,7 +136,7 @@ public class StatusViewHolder extends ViewHolder implements Constants, IStatusVi
TWIDERE_PREVIEW_TEXT_UNESCAPED);
if (text instanceof Spanned) {
textView.setText(linkify.applyAllLinks(text, -1, -1, false,
adapter.getLinkHighlightingStyle()));
adapter.getLinkHighlightingStyle(), true));
}
} else {
textView.setText(toPlainText(TWIDERE_PREVIEW_TEXT_HTML));
@ -206,6 +206,7 @@ public class StatusViewHolder extends ViewHolder implements Constants, IStatusVi
}
boolean skipLinksInText = status.extras != null && status.extras.support_entities;
if (status.is_quote && ArrayUtils.isEmpty(status.media)) {
statusContentSpace.setVisibility(View.VISIBLE);
@ -224,7 +225,7 @@ public class StatusViewHolder extends ViewHolder implements Constants, IStatusVi
if (text instanceof Spanned) {
quotedTextView.setText(linkify.applyAllLinks(text, status.account_id,
getLayoutPosition(), status.is_possibly_sensitive,
adapter.getLinkHighlightingStyle()));
adapter.getLinkHighlightingStyle(), skipLinksInText));
}
} else {
final String text = status.quoted_text_unescaped;
@ -318,7 +319,7 @@ public class StatusViewHolder extends ViewHolder implements Constants, IStatusVi
final CharSequence text = HtmlSpanBuilder.fromHtml(status.text_html, status.text_unescaped);
if (text instanceof Spanned) {
textView.setText(linkify.applyAllLinks(text, status.account_id, getLayoutPosition(),
status.is_possibly_sensitive, adapter.getLinkHighlightingStyle()));
status.is_possibly_sensitive, adapter.getLinkHighlightingStyle(), skipLinksInText));
}
}