mirror of
https://github.com/TwidereProject/Twidere-Android
synced 2025-02-01 17:26:46 +01:00
updated version
This commit is contained in:
parent
183a2ae752
commit
5e0d4544a5
@ -33,15 +33,19 @@ import org.mariotaku.library.objectcursor.annotation.CursorField;
|
||||
import org.mariotaku.library.objectcursor.annotation.CursorObject;
|
||||
import org.mariotaku.twidere.model.util.UserKeyConverter;
|
||||
import org.mariotaku.twidere.model.util.UserKeyCursorFieldConverter;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@ParcelablePlease(allFields = false)
|
||||
@JsonObject
|
||||
@CursorObject(valuesCreator = true)
|
||||
@CursorObject(valuesCreator = true, tableInfo = true)
|
||||
public class ParcelableDirectMessage implements Parcelable, Comparable<ParcelableDirectMessage> {
|
||||
|
||||
@ParcelableThisPlease
|
||||
@CursorField(value = DirectMessages._ID, type = TwidereDataStore.TYPE_PRIMARY_KEY, excludeWrite = true)
|
||||
public long _id;
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "account_id", typeConverter = UserKeyConverter.class)
|
||||
@CursorField(value = DirectMessages.ACCOUNT_KEY, converter = UserKeyCursorFieldConverter.class)
|
||||
@ -70,17 +74,18 @@ public class ParcelableDirectMessage implements Parcelable, Comparable<Parcelabl
|
||||
public boolean is_outgoing;
|
||||
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "text_html")
|
||||
@CursorField(DirectMessages.TEXT_HTML)
|
||||
public String text_html;
|
||||
@JsonField(name = "text_unescaped")
|
||||
@CursorField(DirectMessages.TEXT_UNESCAPED)
|
||||
public String text_unescaped;
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "text_plain")
|
||||
@CursorField(DirectMessages.TEXT_PLAIN)
|
||||
public String text_plain;
|
||||
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "text_unescaped")
|
||||
@CursorField(DirectMessages.TEXT_UNESCAPED)
|
||||
public String text_unescaped;
|
||||
@JsonField(name = "spans")
|
||||
@CursorField(value = DirectMessages.SPANS, converter = LoganSquareCursorFieldConverter.class)
|
||||
public SpanItem[] spans;
|
||||
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "sender_name")
|
||||
@ -108,6 +113,11 @@ public class ParcelableDirectMessage implements Parcelable, Comparable<Parcelabl
|
||||
@CursorField(DirectMessages.RECIPIENT_PROFILE_IMAGE_URL)
|
||||
public String recipient_profile_image_url;
|
||||
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "conversation_id")
|
||||
@CursorField(DirectMessages.CONVERSATION_ID)
|
||||
public String conversation_id;
|
||||
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "media")
|
||||
@CursorField(value = DirectMessages.MEDIA_JSON, converter = LoganSquareCursorFieldConverter.class)
|
||||
@ -147,14 +157,14 @@ public class ParcelableDirectMessage implements Parcelable, Comparable<Parcelabl
|
||||
public String toString() {
|
||||
return "ParcelableDirectMessage{" +
|
||||
"account_key=" + account_key +
|
||||
", id=" + id +
|
||||
", id='" + id + '\'' +
|
||||
", timestamp=" + timestamp +
|
||||
", sender_id=" + sender_id +
|
||||
", recipient_id=" + recipient_id +
|
||||
", sender_id='" + sender_id + '\'' +
|
||||
", recipient_id='" + recipient_id + '\'' +
|
||||
", is_outgoing=" + is_outgoing +
|
||||
", text_html='" + text_html + '\'' +
|
||||
", text_plain='" + text_plain + '\'' +
|
||||
", text_unescaped='" + text_unescaped + '\'' +
|
||||
", text_plain='" + text_plain + '\'' +
|
||||
", spans=" + Arrays.toString(spans) +
|
||||
", sender_name='" + sender_name + '\'' +
|
||||
", recipient_name='" + recipient_name + '\'' +
|
||||
", sender_screen_name='" + sender_screen_name + '\'' +
|
||||
|
@ -32,10 +32,14 @@ import org.mariotaku.commons.objectcursor.LoganSquareCursorFieldConverter;
|
||||
import org.mariotaku.library.objectcursor.annotation.AfterCursorObjectCreated;
|
||||
import org.mariotaku.library.objectcursor.annotation.CursorField;
|
||||
import org.mariotaku.library.objectcursor.annotation.CursorObject;
|
||||
import org.mariotaku.microblog.library.twitter.model.DirectMessage;
|
||||
import org.mariotaku.twidere.model.util.UserKeyConverter;
|
||||
import org.mariotaku.twidere.model.util.UserKeyCursorFieldConverter;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
|
||||
@ParcelablePlease(allFields = false)
|
||||
@JsonObject
|
||||
@ -114,17 +118,14 @@ public class ParcelableUser implements Parcelable, Comparable<ParcelableUser> {
|
||||
@CursorField(CachedUsers.URL_EXPANDED)
|
||||
public String url_expanded;
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "description_html")
|
||||
@CursorField(CachedUsers.DESCRIPTION_HTML)
|
||||
public String description_html;
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "description_unescaped")
|
||||
@CursorField(CachedUsers.DESCRIPTION_UNESCAPED)
|
||||
public String description_unescaped;
|
||||
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "description_expanded")
|
||||
@CursorField(CachedUsers.DESCRIPTION_EXPANDED)
|
||||
public String description_expanded;
|
||||
@JsonField(name = "description_spans")
|
||||
@CursorField(value = CachedUsers.DESCRIPTION_SPANS, converter = LoganSquareCursorFieldConverter.class)
|
||||
public SpanItem[] description_spans;
|
||||
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "followers_count")
|
||||
@ -272,9 +273,8 @@ public class ParcelableUser implements Parcelable, Comparable<ParcelableUser> {
|
||||
", profile_background_url='" + profile_background_url + '\'' +
|
||||
", url='" + url + '\'' +
|
||||
", url_expanded='" + url_expanded + '\'' +
|
||||
", description_html='" + description_html + '\'' +
|
||||
", description_unescaped='" + description_unescaped + '\'' +
|
||||
", description_expanded='" + description_expanded + '\'' +
|
||||
", description_spans=" + Arrays.toString(description_spans) +
|
||||
", followers_count=" + followers_count +
|
||||
", friends_count=" + friends_count +
|
||||
", statuses_count=" + statuses_count +
|
||||
|
@ -24,6 +24,7 @@ import android.net.Uri;
|
||||
import android.provider.BaseColumns;
|
||||
|
||||
import org.mariotaku.twidere.model.ParcelableActivityTableInfo;
|
||||
import org.mariotaku.twidere.model.ParcelableDirectMessageTableInfo;
|
||||
import org.mariotaku.twidere.model.ParcelableStatusTableInfo;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@ -252,11 +253,9 @@ public interface TwidereDataStore {
|
||||
|
||||
String DESCRIPTION_PLAIN = "description_plain";
|
||||
|
||||
String DESCRIPTION_HTML = "description_html";
|
||||
|
||||
String DESCRIPTION_UNESCAPED = "description_unescaped";
|
||||
|
||||
String DESCRIPTION_EXPANDED = "description_expanded";
|
||||
String DESCRIPTION_SPANS = "description_spans";
|
||||
|
||||
String LOCATION = "location";
|
||||
|
||||
@ -306,7 +305,7 @@ public interface TwidereDataStore {
|
||||
String[] COLUMNS = {_ID, USER_KEY, CREATED_AT, NAME, SCREEN_NAME, DESCRIPTION_PLAIN, LOCATION,
|
||||
URL, PROFILE_IMAGE_URL, PROFILE_BANNER_URL, PROFILE_BACKGROUND_URL, IS_PROTECTED,
|
||||
IS_VERIFIED, IS_FOLLOWING, FOLLOWERS_COUNT, FRIENDS_COUNT, STATUSES_COUNT,
|
||||
FAVORITES_COUNT, LISTED_COUNT, MEDIA_COUNT, DESCRIPTION_HTML, DESCRIPTION_EXPANDED,
|
||||
FAVORITES_COUNT, LISTED_COUNT, MEDIA_COUNT, DESCRIPTION_SPANS,
|
||||
URL_EXPANDED, BACKGROUND_COLOR, LINK_COLOR, TEXT_COLOR, LAST_SEEN,
|
||||
DESCRIPTION_UNESCAPED, EXTRAS};
|
||||
|
||||
@ -315,7 +314,7 @@ public interface TwidereDataStore {
|
||||
String[] TYPES = {TYPE_PRIMARY_KEY, TYPE_TEXT_NOT_NULL, TYPE_INT, TYPE_TEXT, TYPE_TEXT,
|
||||
TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_BOOLEAN,
|
||||
TYPE_BOOLEAN, TYPE_BOOLEAN, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT,
|
||||
TYPE_INT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT,
|
||||
TYPE_INT, TYPE_TEXT, TYPE_TEXT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT,
|
||||
TYPE_TEXT, TYPE_TEXT};
|
||||
|
||||
}
|
||||
@ -404,9 +403,9 @@ public interface TwidereDataStore {
|
||||
|
||||
String IS_OUTGOING = "is_outgoing";
|
||||
|
||||
String TEXT_HTML = "text_html";
|
||||
String TEXT_PLAIN = "text_plain";
|
||||
String TEXT_UNESCAPED = "text_unescaped";
|
||||
String SPANS = "spans";
|
||||
String SENDER_NAME = "sender_name";
|
||||
String RECIPIENT_NAME = "recipient_name";
|
||||
String SENDER_SCREEN_NAME = "sender_screen_name";
|
||||
@ -416,13 +415,8 @@ public interface TwidereDataStore {
|
||||
|
||||
String MEDIA_JSON = "media_json";
|
||||
|
||||
String[] COLUMNS = {_ID, ACCOUNT_KEY, MESSAGE_ID, MESSAGE_TIMESTAMP,
|
||||
SENDER_ID, RECIPIENT_ID, CONVERSATION_ID, IS_OUTGOING, TEXT_HTML, TEXT_PLAIN, TEXT_UNESCAPED,
|
||||
SENDER_NAME, RECIPIENT_NAME, SENDER_SCREEN_NAME, RECIPIENT_SCREEN_NAME, SENDER_PROFILE_IMAGE_URL,
|
||||
RECIPIENT_PROFILE_IMAGE_URL, MEDIA_JSON, INSERTED_DATE};
|
||||
String[] TYPES = {TYPE_PRIMARY_KEY, TYPE_TEXT_NOT_NULL, TYPE_TEXT_NOT_NULL, TYPE_INT,
|
||||
TYPE_TEXT_NOT_NULL, TYPE_TEXT_NOT_NULL, TYPE_INT, TYPE_BOOLEAN, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT,
|
||||
TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, INSERTED_DATE_TYPE};
|
||||
String[] COLUMNS = ParcelableDirectMessageTableInfo.COLUMNS;
|
||||
String[] TYPES = ParcelableDirectMessageTableInfo.TYPES;
|
||||
|
||||
String DEFAULT_SORT_ORDER = MESSAGE_ID + " DESC";
|
||||
|
||||
@ -460,7 +454,7 @@ public interface TwidereDataStore {
|
||||
String NAME = "name";
|
||||
String SCREEN_NAME = "screen_name";
|
||||
String PROFILE_IMAGE_URL = "profile_image_url";
|
||||
String TEXT_HTML = DirectMessages.TEXT_HTML;
|
||||
String TEXT_UNESCAPED = "text_unescaped";
|
||||
String CONVERSATION_ID = "conversation_id";
|
||||
|
||||
int IDX__ID = 0;
|
||||
@ -471,7 +465,7 @@ public interface TwidereDataStore {
|
||||
int IDX_NAME = 5;
|
||||
int IDX_SCREEN_NAME = 6;
|
||||
int IDX_PROFILE_IMAGE_URL = 7;
|
||||
int IDX_TEXT = 8;
|
||||
int IDX_TEXT_UNESCAPED = 8;
|
||||
int IDX_CONVERSATION_ID = 9;
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ import static org.mariotaku.twidere.annotation.PreferenceType.STRING;
|
||||
public interface Constants extends TwidereConstants {
|
||||
|
||||
String DATABASES_NAME = "twidere.sqlite";
|
||||
int DATABASES_VERSION = 145;
|
||||
int DATABASES_VERSION = 150;
|
||||
|
||||
int MENU_GROUP_STATUS_EXTENSION = 10;
|
||||
int MENU_GROUP_COMPOSE_EXTENSION = 11;
|
||||
|
@ -58,7 +58,7 @@ import android.support.v4.view.WindowCompat;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
import android.text.util.Linkify;
|
||||
import android.util.Log;
|
||||
@ -125,6 +125,7 @@ import org.mariotaku.twidere.model.message.TaskStateChangedEvent;
|
||||
import org.mariotaku.twidere.model.util.ParcelableAccountUtils;
|
||||
import org.mariotaku.twidere.model.util.ParcelableCredentialsUtils;
|
||||
import org.mariotaku.twidere.model.util.ParcelableMediaUtils;
|
||||
import org.mariotaku.twidere.model.util.ParcelableStatusUtils;
|
||||
import org.mariotaku.twidere.model.util.ParcelableUserUtils;
|
||||
import org.mariotaku.twidere.model.util.UserKeyUtils;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.CachedRelationships;
|
||||
@ -133,7 +134,6 @@ import org.mariotaku.twidere.provider.TwidereDataStore.Filters;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
import org.mariotaku.twidere.util.ContentValuesCreator;
|
||||
import org.mariotaku.twidere.util.DataStoreUtils;
|
||||
import org.mariotaku.twidere.util.HtmlSpanBuilder;
|
||||
import org.mariotaku.twidere.util.IntentUtils;
|
||||
import org.mariotaku.twidere.util.InternalTwitterContentUtils;
|
||||
import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
|
||||
@ -553,16 +553,17 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
mProfileTypeView.setVisibility(View.GONE);
|
||||
}
|
||||
mScreenNameView.setText(String.format("@%s", user.screen_name));
|
||||
mDescriptionContainer.setVisibility(TextUtils.isEmpty(user.description_html) ? View.GONE : View.VISIBLE);
|
||||
final TwidereLinkify linkify = new TwidereLinkify(this);
|
||||
if (user.description_html != null) {
|
||||
final Spannable text = HtmlSpanBuilder.fromHtml(user.description_html);
|
||||
if (user.description_unescaped != null) {
|
||||
final SpannableStringBuilder text = SpannableStringBuilder.valueOf(user.description_unescaped);
|
||||
ParcelableStatusUtils.applySpans(text, user.description_spans);
|
||||
linkify.applyAllLinks(text, user.account_key, false, false);
|
||||
mDescriptionView.setText(text);
|
||||
} else {
|
||||
mDescriptionView.setText(user.description_plain);
|
||||
Linkify.addLinks(mDescriptionView, Linkify.WEB_URLS);
|
||||
}
|
||||
mDescriptionContainer.setVisibility(mDescriptionView.length() > 0 ? View.VISIBLE : View.GONE);
|
||||
|
||||
mLocationContainer.setVisibility(TextUtils.isEmpty(user.location) ? View.GONE : View.VISIBLE);
|
||||
mLocationView.setText(user.location);
|
||||
|
@ -258,7 +258,7 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On
|
||||
displayUser(user);
|
||||
mEditName.setText(savedInstanceState.getString(EXTRA_NAME, user.name));
|
||||
mEditLocation.setText(savedInstanceState.getString(EXTRA_LOCATION, user.location));
|
||||
mEditDescription.setText(savedInstanceState.getString(EXTRA_DESCRIPTION, user.description_expanded));
|
||||
mEditDescription.setText(savedInstanceState.getString(EXTRA_DESCRIPTION, ParcelableUserUtils.getExpandedDescription(user)));
|
||||
mEditUrl.setText(savedInstanceState.getString(EXTRA_URL, user.url_expanded));
|
||||
} else {
|
||||
getUserInfo();
|
||||
@ -359,7 +359,7 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On
|
||||
mProgressContainer.setVisibility(View.GONE);
|
||||
mEditProfileContent.setVisibility(View.VISIBLE);
|
||||
mEditName.setText(user.name);
|
||||
mEditDescription.setText(user.description_expanded);
|
||||
mEditDescription.setText(ParcelableUserUtils.getExpandedDescription(user));
|
||||
mEditLocation.setText(user.location);
|
||||
mEditUrl.setText(isEmpty(user.url_expanded) ? user.url : user.url_expanded);
|
||||
mMediaLoader.displayProfileImage(mProfileImageView, user);
|
||||
@ -515,7 +515,7 @@ public class UserProfileEditorFragment extends BaseSupportFragment implements On
|
||||
if (mLinkColor != orig.link_color) return true;
|
||||
if (mBackgroundColor != orig.background_color) return true;
|
||||
if (!stringEquals(mName, orig.name)) return true;
|
||||
if (!stringEquals(mDescription, isEmpty(orig.description_expanded) ? orig.description_plain : orig.description_expanded))
|
||||
if (!stringEquals(mDescription, ParcelableUserUtils.getExpandedDescription(orig)))
|
||||
return true;
|
||||
if (!stringEquals(mLocation, orig.location)) return true;
|
||||
if (!stringEquals(mUrl, isEmpty(orig.url_expanded) ? orig.url : orig.url_expanded))
|
||||
|
@ -1,16 +1,17 @@
|
||||
package org.mariotaku.twidere.model.util;
|
||||
|
||||
import android.support.v4.util.Pair;
|
||||
|
||||
import org.mariotaku.microblog.library.twitter.model.DirectMessage;
|
||||
import org.mariotaku.microblog.library.twitter.model.User;
|
||||
import org.mariotaku.twidere.model.ParcelableDirectMessage;
|
||||
import org.mariotaku.twidere.model.SpanItem;
|
||||
import org.mariotaku.twidere.model.UserKey;
|
||||
import org.mariotaku.twidere.util.InternalTwitterContentUtils;
|
||||
import org.mariotaku.twidere.util.TwitterContentUtils;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import static org.mariotaku.twidere.util.HtmlEscapeHelper.toPlainText;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/2/13.
|
||||
*/
|
||||
@ -31,7 +32,9 @@ public class ParcelableDirectMessageUtils {
|
||||
result.timestamp = getTime(message.getCreatedAt());
|
||||
result.sender_id = sender.getId();
|
||||
result.recipient_id = recipient.getId();
|
||||
result.text_html = InternalTwitterContentUtils.formatDirectMessageText(message);
|
||||
final Pair<String, SpanItem[]> pair = InternalTwitterContentUtils.formatDirectMessageText(message);
|
||||
result.text_unescaped = pair.first;
|
||||
result.spans = pair.second;
|
||||
result.text_plain = message.getText();
|
||||
result.sender_name = sender.getName();
|
||||
result.recipient_name = recipient.getName();
|
||||
@ -39,8 +42,12 @@ public class ParcelableDirectMessageUtils {
|
||||
result.recipient_screen_name = recipient.getScreenName();
|
||||
result.sender_profile_image_url = sender_profile_image_url;
|
||||
result.recipient_profile_image_url = recipient_profile_image_url;
|
||||
result.text_unescaped = toPlainText(result.text_html);
|
||||
result.media = ParcelableMediaUtils.fromEntities(message);
|
||||
if (isOutgoing) {
|
||||
result.conversation_id = result.recipient_id;
|
||||
} else {
|
||||
result.conversation_id = result.sender_id;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ package org.mariotaku.twidere.model.util;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spannable;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextUtils;
|
||||
import android.text.style.URLSpan;
|
||||
@ -25,7 +25,6 @@ import org.mariotaku.twidere.util.TwitterContentUtils;
|
||||
import org.mariotaku.twidere.util.UserColorNameManager;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import static org.mariotaku.twidere.TwidereConstants.USER_TYPE_FANFOU_COM;
|
||||
|
||||
@ -91,10 +90,10 @@ public class ParcelableStatusUtils {
|
||||
result.quoted_text_plain = result.quoted_text_unescaped;
|
||||
result.quoted_spans = getSpanItems(html);
|
||||
} else {
|
||||
final Pair<String, List<SpanItem>> textWithIndices = InternalTwitterContentUtils.formatStatusTextWithIndices(quoted);
|
||||
final Pair<String, SpanItem[]> textWithIndices = InternalTwitterContentUtils.formatStatusTextWithIndices(quoted);
|
||||
result.quoted_text_plain = InternalTwitterContentUtils.unescapeTwitterStatusText(quotedText);
|
||||
result.quoted_text_unescaped = textWithIndices.first;
|
||||
result.quoted_spans = textWithIndices.second.toArray(new SpanItem[textWithIndices.second.size()]);
|
||||
result.quoted_spans = textWithIndices.second;
|
||||
}
|
||||
|
||||
result.quoted_timestamp = quoted.getCreatedAt().getTime();
|
||||
@ -158,10 +157,10 @@ public class ParcelableStatusUtils {
|
||||
result.text_plain = result.text_unescaped;
|
||||
result.spans = getSpanItems(html);
|
||||
} else {
|
||||
final Pair<String, List<SpanItem>> textWithIndices = InternalTwitterContentUtils.formatStatusTextWithIndices(status);
|
||||
final Pair<String, SpanItem[]> textWithIndices = InternalTwitterContentUtils.formatStatusTextWithIndices(status);
|
||||
result.text_unescaped = textWithIndices.first;
|
||||
result.text_plain = InternalTwitterContentUtils.unescapeTwitterStatusText(text);
|
||||
result.spans = textWithIndices.second.toArray(new SpanItem[textWithIndices.second.size()]);
|
||||
result.spans = textWithIndices.second;
|
||||
}
|
||||
result.media = ParcelableMediaUtils.fromStatus(status);
|
||||
result.source = status.getSource();
|
||||
@ -284,7 +283,7 @@ public class ParcelableStatusUtils {
|
||||
return status.getInReplyToScreenName();
|
||||
}
|
||||
|
||||
public static void applySpans(@NonNull SpannableStringBuilder text, @Nullable SpanItem[] spans) {
|
||||
public static void applySpans(@NonNull Spannable text, @Nullable SpanItem[] spans) {
|
||||
if (spans == null) return;
|
||||
for (SpanItem span : spans) {
|
||||
text.setSpan(new URLSpan(span.link), span.start, span.end,
|
||||
|
@ -3,6 +3,7 @@ package org.mariotaku.twidere.model.util;
|
||||
import android.database.Cursor;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import org.mariotaku.microblog.library.twitter.model.UrlEntity;
|
||||
@ -10,9 +11,9 @@ import org.mariotaku.microblog.library.twitter.model.User;
|
||||
import org.mariotaku.twidere.TwidereConstants;
|
||||
import org.mariotaku.twidere.model.ParcelableAccount;
|
||||
import org.mariotaku.twidere.model.ParcelableUser;
|
||||
import org.mariotaku.twidere.model.SpanItem;
|
||||
import org.mariotaku.twidere.model.UserKey;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages;
|
||||
import org.mariotaku.twidere.util.HtmlEscapeHelper;
|
||||
import org.mariotaku.twidere.util.InternalTwitterContentUtils;
|
||||
import org.mariotaku.twidere.util.ParseUtils;
|
||||
import org.mariotaku.twidere.util.TwitterContentUtils;
|
||||
@ -43,9 +44,9 @@ public class ParcelableUserUtils implements TwidereConstants {
|
||||
obj.name = user.getName();
|
||||
obj.screen_name = user.getScreenName();
|
||||
obj.description_plain = user.getDescription();
|
||||
obj.description_html = InternalTwitterContentUtils.formatUserDescription(user);
|
||||
obj.description_expanded = InternalTwitterContentUtils.formatExpandedUserDescription(user);
|
||||
obj.description_unescaped = HtmlEscapeHelper.toPlainText(obj.description_html);
|
||||
final Pair<String, SpanItem[]> userDescription = InternalTwitterContentUtils.formatUserDescription(user);
|
||||
obj.description_unescaped = userDescription.first;
|
||||
obj.description_spans = userDescription.second;
|
||||
obj.location = user.getLocation();
|
||||
obj.profile_image_url = TwitterContentUtils.getProfileImageUrl(user);
|
||||
obj.profile_banner_url = user.getProfileBannerImageUrl();
|
||||
@ -129,4 +130,14 @@ public class ParcelableUserUtils implements TwidereConstants {
|
||||
user.color = manager.getUserColor(user.key);
|
||||
user.nickname = manager.getUserNickname(user.key);
|
||||
}
|
||||
|
||||
public static String getExpandedDescription(ParcelableUser user) {
|
||||
if (TextUtils.isEmpty(user.description_unescaped)) {
|
||||
return user.description_plain;
|
||||
}
|
||||
if (user.description_spans != null) {
|
||||
// TODO expand description
|
||||
}
|
||||
return user.description_unescaped;
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,6 @@ import org.mariotaku.twidere.model.ParcelableActivityValuesCreator;
|
||||
import org.mariotaku.twidere.model.ParcelableCredentials;
|
||||
import org.mariotaku.twidere.model.ParcelableDirectMessage;
|
||||
import org.mariotaku.twidere.model.ParcelableDirectMessageValuesCreator;
|
||||
import org.mariotaku.twidere.model.ParcelableMedia;
|
||||
import org.mariotaku.twidere.model.ParcelableMediaUpdate;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.model.ParcelableStatusValuesCreator;
|
||||
@ -48,11 +47,10 @@ import org.mariotaku.twidere.model.ParcelableUserValuesCreator;
|
||||
import org.mariotaku.twidere.model.UserKey;
|
||||
import org.mariotaku.twidere.model.draft.SendDirectMessageActionExtra;
|
||||
import org.mariotaku.twidere.model.util.ParcelableActivityUtils;
|
||||
import org.mariotaku.twidere.model.util.ParcelableMediaUtils;
|
||||
import org.mariotaku.twidere.model.util.ParcelableDirectMessageUtils;
|
||||
import org.mariotaku.twidere.model.util.ParcelableStatusUtils;
|
||||
import org.mariotaku.twidere.model.util.ParcelableUserUtils;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Filters;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.SavedSearches;
|
||||
@ -82,37 +80,8 @@ public final class ContentValuesCreator implements TwidereConstants {
|
||||
public static ContentValues createDirectMessage(final DirectMessage message,
|
||||
final UserKey accountKey,
|
||||
final boolean isOutgoing) {
|
||||
if (message == null) return null;
|
||||
final ContentValues values = new ContentValues();
|
||||
final User sender = message.getSender(), recipient = message.getRecipient();
|
||||
if (sender == null || recipient == null) return null;
|
||||
final String sender_profile_image_url = TwitterContentUtils.getProfileImageUrl(sender);
|
||||
final String recipient_profile_image_url = TwitterContentUtils.getProfileImageUrl(recipient);
|
||||
values.put(DirectMessages.ACCOUNT_KEY, accountKey.toString());
|
||||
values.put(DirectMessages.MESSAGE_ID, message.getId());
|
||||
values.put(DirectMessages.MESSAGE_TIMESTAMP, message.getCreatedAt().getTime());
|
||||
values.put(DirectMessages.SENDER_ID, sender.getId());
|
||||
values.put(DirectMessages.RECIPIENT_ID, recipient.getId());
|
||||
if (isOutgoing) {
|
||||
values.put(DirectMessages.CONVERSATION_ID, recipient.getId());
|
||||
} else {
|
||||
values.put(DirectMessages.CONVERSATION_ID, sender.getId());
|
||||
}
|
||||
final String text_html = InternalTwitterContentUtils.formatDirectMessageText(message);
|
||||
values.put(DirectMessages.TEXT_HTML, text_html);
|
||||
values.put(DirectMessages.TEXT_PLAIN, message.getText());
|
||||
values.put(DirectMessages.TEXT_UNESCAPED, HtmlEscapeHelper.toPlainText(text_html));
|
||||
values.put(DirectMessages.IS_OUTGOING, isOutgoing);
|
||||
values.put(DirectMessages.SENDER_NAME, sender.getName());
|
||||
values.put(DirectMessages.SENDER_SCREEN_NAME, sender.getScreenName());
|
||||
values.put(DirectMessages.RECIPIENT_NAME, recipient.getName());
|
||||
values.put(DirectMessages.RECIPIENT_SCREEN_NAME, recipient.getScreenName());
|
||||
values.put(DirectMessages.SENDER_PROFILE_IMAGE_URL, sender_profile_image_url);
|
||||
values.put(DirectMessages.RECIPIENT_PROFILE_IMAGE_URL, recipient_profile_image_url);
|
||||
final ParcelableMedia[] mediaArray = ParcelableMediaUtils.fromEntities(message);
|
||||
values.put(DirectMessages.MEDIA_JSON, JsonSerializer.serialize(Arrays.asList(mediaArray),
|
||||
ParcelableMedia.class));
|
||||
return values;
|
||||
return ParcelableDirectMessageValuesCreator.create(ParcelableDirectMessageUtils.fromDirectMessage(message,
|
||||
accountKey, isOutgoing));
|
||||
}
|
||||
|
||||
public static ContentValues createDirectMessage(final ParcelableDirectMessage message) {
|
||||
|
@ -26,7 +26,6 @@ import org.mariotaku.twidere.model.SpanItem;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static android.text.TextUtils.isEmpty;
|
||||
@ -39,7 +38,7 @@ public class HtmlBuilder {
|
||||
private final int sourceLength;
|
||||
private final boolean throwExceptions, sourceIsEscaped, shouldReEscape;
|
||||
|
||||
private final ArrayList<LinkSpec> links = new ArrayList<>();
|
||||
private final ArrayList<SpanSpec> spanSpecs = new ArrayList<>();
|
||||
|
||||
public HtmlBuilder(final String source, final boolean strict, final boolean sourceIsEscaped,
|
||||
final boolean shouldReEscape) {
|
||||
@ -61,7 +60,7 @@ public class HtmlBuilder {
|
||||
}
|
||||
|
||||
public boolean addLink(final String link, final String display, final int start, final int end,
|
||||
final boolean display_is_html) {
|
||||
final boolean displayIsHtml) {
|
||||
if (start < 0 || end < 0 || start > end || end > sourceLength) {
|
||||
final String message = String.format(Locale.US, "text:%s, length:%d, start:%d, end:%d", source,
|
||||
sourceLength, start, end);
|
||||
@ -75,83 +74,39 @@ public class HtmlBuilder {
|
||||
if (throwExceptions) throw new IllegalArgumentException(message);
|
||||
return false;
|
||||
}
|
||||
return links.add(new LinkSpec(link, display, start, end, display_is_html));
|
||||
return spanSpecs.add(new LinkSpec(link, display, start, end, displayIsHtml));
|
||||
}
|
||||
|
||||
public String build() {
|
||||
if (links.isEmpty()) return escapeSource();
|
||||
Collections.sort(links);
|
||||
public Pair<String, SpanItem[]> buildWithIndices() {
|
||||
if (spanSpecs.isEmpty()) return Pair.create(escapeSource(), new SpanItem[0]);
|
||||
Collections.sort(spanSpecs);
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
final int linksSize = links.size();
|
||||
final int linksSize = spanSpecs.size();
|
||||
SpanItem[] items = new SpanItem[linksSize];
|
||||
for (int i = 0; i < linksSize; i++) {
|
||||
final LinkSpec spec = links.get(i);
|
||||
if (spec == null) {
|
||||
continue;
|
||||
}
|
||||
final int start = spec.start, end = spec.end;
|
||||
if (i == 0) {
|
||||
if (start >= 0 && start <= sourceLength) {
|
||||
appendSource(sb, 0, start, shouldReEscape, sourceIsEscaped);
|
||||
}
|
||||
} else if (i > 0) {
|
||||
final int lastEnd = links.get(i - 1).end;
|
||||
if (lastEnd >= 0 && lastEnd <= start && start <= sourceLength) {
|
||||
appendSource(sb, lastEnd, start, shouldReEscape, sourceIsEscaped);
|
||||
}
|
||||
}
|
||||
sb.append("<a href=\"");
|
||||
sb.append(spec.link);
|
||||
sb.append("\">");
|
||||
if (start >= 0 && start <= end && end <= sourceLength) {
|
||||
if (isEmpty(spec.display)) {
|
||||
append(sb, spec.link, shouldReEscape, false);
|
||||
} else {
|
||||
append(sb, spec.display, shouldReEscape, spec.displayIsHtml);
|
||||
}
|
||||
}
|
||||
sb.append("</a>");
|
||||
if (i == linksSize - 1 && end >= 0 && end <= sourceLength) {
|
||||
appendSource(sb, end, sourceLength, shouldReEscape, sourceIsEscaped);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public Pair<String, List<SpanItem>> buildWithIndices() {
|
||||
List<SpanItem> items = new ArrayList<>();
|
||||
if (links.isEmpty()) return Pair.create(escapeSource(), items);
|
||||
Collections.sort(links);
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
final int linksSize = links.size();
|
||||
for (int i = 0; i < linksSize; i++) {
|
||||
final LinkSpec spec = links.get(i);
|
||||
if (spec == null) {
|
||||
continue;
|
||||
}
|
||||
final int start = spec.start, end = spec.end;
|
||||
final SpanSpec spec = spanSpecs.get(i);
|
||||
final int start = spec.getStart(), end = spec.getEnd();
|
||||
if (i == 0) {
|
||||
if (start >= 0 && start <= sourceLength) {
|
||||
appendSource(sb, 0, start, false, sourceIsEscaped);
|
||||
}
|
||||
} else if (i > 0) {
|
||||
final int lastEnd = links.get(i - 1).end;
|
||||
final int lastEnd = spanSpecs.get(i - 1).end;
|
||||
if (lastEnd >= 0 && lastEnd <= start && start <= sourceLength) {
|
||||
appendSource(sb, lastEnd, start, false, sourceIsEscaped);
|
||||
}
|
||||
}
|
||||
int spanStart = sb.length();
|
||||
if (start >= 0 && start <= end && end <= sourceLength) {
|
||||
if (isEmpty(spec.display)) {
|
||||
append(sb, spec.link, false, false);
|
||||
} else {
|
||||
append(sb, spec.display, false, spec.displayIsHtml);
|
||||
}
|
||||
spec.appendTo(sb);
|
||||
}
|
||||
final SpanItem item = new SpanItem();
|
||||
item.start = spanStart;
|
||||
item.end = sb.length();
|
||||
item.link = spec.link;
|
||||
items.add(item);
|
||||
if (spec instanceof LinkSpec) {
|
||||
item.link = ((LinkSpec) spec).link;
|
||||
}
|
||||
items[i] = item;
|
||||
if (i == linksSize - 1 && end >= 0 && end <= sourceLength) {
|
||||
appendSource(sb, end, sourceLength, false, sourceIsEscaped);
|
||||
}
|
||||
@ -160,10 +115,12 @@ public class HtmlBuilder {
|
||||
}
|
||||
|
||||
public boolean hasLink(final int start, final int end) {
|
||||
for (final LinkSpec spec : links) {
|
||||
if (start >= spec.start && start <= spec.end || end >= spec.start && end <= spec.end)
|
||||
for (final SpanSpec spec : spanSpecs) {
|
||||
final int specStart = spec.getStart(), specEnd = spec.getEnd();
|
||||
if (start >= specStart && start <= specEnd || end >= specStart && end <= specEnd) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -175,7 +132,7 @@ public class HtmlBuilder {
|
||||
", throwExceptions=" + throwExceptions +
|
||||
", sourceIsEscaped=" + sourceIsEscaped +
|
||||
", shouldReEscape=" + shouldReEscape +
|
||||
", links=" + links +
|
||||
", links=" + spanSpecs +
|
||||
'}';
|
||||
}
|
||||
|
||||
@ -189,7 +146,7 @@ public class HtmlBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
private void append(final StringBuilder builder, final String text, boolean escapeText, boolean textEscaped) {
|
||||
private static void append(final StringBuilder builder, final String text, boolean escapeText, boolean textEscaped) {
|
||||
if (textEscaped == escapeText) {
|
||||
builder.append(text);
|
||||
} else if (escapeText) {
|
||||
@ -205,52 +162,101 @@ public class HtmlBuilder {
|
||||
return shouldReEscape ? escape(source) : unescape(source);
|
||||
}
|
||||
|
||||
static final class LinkSpec implements Comparable<LinkSpec> {
|
||||
static abstract class SpanSpec implements Comparable<SpanSpec> {
|
||||
|
||||
final String link, display;
|
||||
final int start, end;
|
||||
final boolean displayIsHtml;
|
||||
|
||||
LinkSpec(final String link, final String display, final int start, final int end, final boolean displayIsHtml) {
|
||||
this.link = link;
|
||||
this.display = display;
|
||||
public final int getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public final int getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
public SpanSpec(int start, int end) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.displayIsHtml = displayIsHtml;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@NonNull final LinkSpec that) {
|
||||
public int compareTo(@NonNull final SpanSpec that) {
|
||||
return start - that.start;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (obj == null) return false;
|
||||
if (!(obj instanceof LinkSpec)) return false;
|
||||
final LinkSpec other = (LinkSpec) obj;
|
||||
if (display == null) {
|
||||
if (other.display != null) return false;
|
||||
} else if (!display.equals(other.display)) return false;
|
||||
if (displayIsHtml != other.displayIsHtml) return false;
|
||||
if (end != other.end) return false;
|
||||
if (link == null) {
|
||||
if (other.link != null) return false;
|
||||
} else if (!link.equals(other.link)) return false;
|
||||
if (start != other.start) return false;
|
||||
return true;
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
SpanSpec spanSpec = (SpanSpec) o;
|
||||
|
||||
if (start != spanSpec.start) return false;
|
||||
return end == spanSpec.end;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (display == null ? 0 : display.hashCode());
|
||||
result = prime * result + (displayIsHtml ? 1231 : 1237);
|
||||
result = prime * result + end;
|
||||
result = prime * result + (link == null ? 0 : link.hashCode());
|
||||
result = prime * result + start;
|
||||
int result = start;
|
||||
result = 31 * result + end;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SpanSpec{" +
|
||||
"start=" + start +
|
||||
", end=" + end +
|
||||
'}';
|
||||
}
|
||||
|
||||
public abstract void appendTo(StringBuilder sb);
|
||||
}
|
||||
|
||||
static final class LinkSpec extends SpanSpec {
|
||||
|
||||
final String link, display;
|
||||
|
||||
final boolean displayIsHtml;
|
||||
|
||||
LinkSpec(final String link, final String display, final int start, final int end, final boolean displayIsHtml) {
|
||||
super(start, end);
|
||||
this.link = link;
|
||||
this.display = display;
|
||||
this.displayIsHtml = displayIsHtml;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void appendTo(StringBuilder sb) {
|
||||
if (isEmpty(display)) {
|
||||
append(sb, link, false, false);
|
||||
} else {
|
||||
append(sb, display, false, displayIsHtml);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (!super.equals(o)) return false;
|
||||
|
||||
LinkSpec linkSpec = (LinkSpec) o;
|
||||
|
||||
if (displayIsHtml != linkSpec.displayIsHtml) return false;
|
||||
if (link != null ? !link.equals(linkSpec.link) : linkSpec.link != null) return false;
|
||||
return display != null ? display.equals(linkSpec.display) : linkSpec.display == null;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = super.hashCode();
|
||||
result = 31 * result + (link != null ? link.hashCode() : 0);
|
||||
result = 31 * result + (display != null ? display.hashCode() : 0);
|
||||
result = 31 * result + (displayIsHtml ? 1 : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -259,10 +265,8 @@ public class HtmlBuilder {
|
||||
return "LinkSpec{" +
|
||||
"link='" + link + '\'' +
|
||||
", display='" + display + '\'' +
|
||||
", start=" + start +
|
||||
", end=" + end +
|
||||
", displayIsHtml=" + displayIsHtml +
|
||||
'}';
|
||||
"} " + super.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,10 +250,10 @@ public class InternalTwitterContentUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
return HtmlEscapeHelper.toPlainText(builder.build());
|
||||
return builder.buildWithIndices().first;
|
||||
}
|
||||
|
||||
public static String formatUserDescription(final User user) {
|
||||
public static Pair<String, SpanItem[]> formatUserDescription(final User user) {
|
||||
if (user == null) return null;
|
||||
final String text = user.getDescription();
|
||||
if (text == null) return null;
|
||||
@ -267,7 +267,7 @@ public class InternalTwitterContentUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
return builder.buildWithIndices();
|
||||
}
|
||||
|
||||
public static String unescapeTwitterStatusText(final CharSequence text) {
|
||||
@ -275,14 +275,14 @@ public class InternalTwitterContentUtils {
|
||||
return UNESCAPE_TWITTER_RAW_TEXT.translate(text);
|
||||
}
|
||||
|
||||
public static String formatDirectMessageText(final DirectMessage message) {
|
||||
public static Pair<String, SpanItem[]> formatDirectMessageText(final DirectMessage message) {
|
||||
if (message == null) return null;
|
||||
final HtmlBuilder builder = new HtmlBuilder(message.getText(), false, true, true);
|
||||
parseEntities(builder, message, null);
|
||||
return builder.build();
|
||||
return builder.buildWithIndices();
|
||||
}
|
||||
|
||||
public static Pair<String, List<SpanItem>> formatStatusTextWithIndices(final Status status) {
|
||||
public static Pair<String, SpanItem[]> formatStatusTextWithIndices(final Status status) {
|
||||
if (status == null) return null;
|
||||
//TODO handle twitter video url
|
||||
|
||||
|
@ -222,7 +222,7 @@ public class TwidereQueryBuilder {
|
||||
new Column(ConversationEntries.NAME),
|
||||
new Column(ConversationEntries.SCREEN_NAME),
|
||||
new Column(ConversationEntries.PROFILE_IMAGE_URL),
|
||||
new Column(ConversationEntries.TEXT_HTML),
|
||||
new Column(ConversationEntries.TEXT_UNESCAPED),
|
||||
new Column(ConversationEntries.CONVERSATION_ID)));
|
||||
final SQLSelectQuery.Builder entryIds = new SQLSelectQuery.Builder();
|
||||
entryIds.select(new Columns(new Column(DirectMessages._ID),
|
||||
@ -233,7 +233,7 @@ public class TwidereQueryBuilder {
|
||||
new Column(DirectMessages.SENDER_NAME, ConversationEntries.NAME),
|
||||
new Column(DirectMessages.SENDER_SCREEN_NAME, ConversationEntries.SCREEN_NAME),
|
||||
new Column(DirectMessages.SENDER_PROFILE_IMAGE_URL, ConversationEntries.PROFILE_IMAGE_URL),
|
||||
new Column(DirectMessages.TEXT_HTML),
|
||||
new Column(DirectMessages.TEXT_UNESCAPED),
|
||||
new Column(DirectMessages.SENDER_ID, ConversationEntries.CONVERSATION_ID)));
|
||||
entryIds.from(new Tables(Inbox.TABLE_NAME));
|
||||
entryIds.union();
|
||||
@ -245,7 +245,7 @@ public class TwidereQueryBuilder {
|
||||
new Column(DirectMessages.RECIPIENT_NAME, ConversationEntries.NAME),
|
||||
new Column(DirectMessages.RECIPIENT_SCREEN_NAME, ConversationEntries.SCREEN_NAME),
|
||||
new Column(DirectMessages.RECIPIENT_PROFILE_IMAGE_URL, ConversationEntries.PROFILE_IMAGE_URL),
|
||||
new Column(DirectMessages.TEXT_HTML),
|
||||
new Column(DirectMessages.TEXT_UNESCAPED),
|
||||
new Column(DirectMessages.RECIPIENT_ID, ConversationEntries.CONVERSATION_ID)));
|
||||
entryIds.from(new Tables(Outbox.TABLE_NAME));
|
||||
qb.from(entryIds.build());
|
||||
|
@ -122,6 +122,9 @@ public final class TwidereSQLiteOpenHelper extends SQLiteOpenHelper implements C
|
||||
}
|
||||
|
||||
private void createViews(SQLiteDatabase db) {
|
||||
db.execSQL(SQLQueryBuilder.dropView(true, DirectMessages.TABLE_NAME).getSQL());
|
||||
db.execSQL(SQLQueryBuilder.dropView(true, DirectMessages.ConversationEntries.TABLE_NAME).getSQL());
|
||||
|
||||
db.execSQL(SQLQueryBuilder.createView(true, DirectMessages.TABLE_NAME)
|
||||
.as(DirectMessagesQueryBuilder.build()).buildSQL());
|
||||
db.execSQL(SQLQueryBuilder.createView(true, DirectMessages.ConversationEntries.TABLE_NAME)
|
||||
|
@ -81,7 +81,7 @@ public class MessageEntryViewHolder extends ViewHolder implements OnClickListene
|
||||
nameView.setName(manager.getUserNickname(conversationId, name));
|
||||
nameView.setScreenName("@" + screenName);
|
||||
nameView.updateText(adapter.getBidiFormatter());
|
||||
textView.setText(toPlainText(cursor.getString(ConversationEntries.IDX_TEXT)));
|
||||
textView.setText(toPlainText(cursor.getString(ConversationEntries.IDX_TEXT_UNESCAPED)));
|
||||
timeView.setTime(timestamp);
|
||||
if (isOutgoing) {
|
||||
timeView.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_indicator_sent, 0);
|
||||
|
@ -24,7 +24,7 @@ import android.content.res.ColorStateList;
|
||||
import android.content.res.TypedArray;
|
||||
import android.database.Cursor;
|
||||
import android.support.v7.widget.RecyclerView.ViewHolder;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
@ -33,8 +33,9 @@ import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.MessageConversationAdapter;
|
||||
import org.mariotaku.twidere.model.ParcelableDirectMessageCursorIndices;
|
||||
import org.mariotaku.twidere.model.ParcelableMedia;
|
||||
import org.mariotaku.twidere.model.SpanItem;
|
||||
import org.mariotaku.twidere.model.UserKey;
|
||||
import org.mariotaku.twidere.util.HtmlSpanBuilder;
|
||||
import org.mariotaku.twidere.model.util.ParcelableStatusUtils;
|
||||
import org.mariotaku.twidere.util.JsonSerializer;
|
||||
import org.mariotaku.twidere.util.MediaLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.ThemeUtils;
|
||||
@ -93,7 +94,10 @@ public class MessageViewHolder extends ViewHolder {
|
||||
final long timestamp = cursor.getLong(indices.timestamp);
|
||||
final ParcelableMedia[] media = JsonSerializer.parseArray(cursor.getString(indices.media),
|
||||
ParcelableMedia.class);
|
||||
final Spannable text = HtmlSpanBuilder.fromHtml(cursor.getString(indices.text_html));
|
||||
final SpanItem[] spans = JsonSerializer.parseArray(cursor.getString(indices.spans),
|
||||
SpanItem.class);
|
||||
final SpannableStringBuilder text = SpannableStringBuilder.valueOf(cursor.getString(indices.text_unescaped));
|
||||
ParcelableStatusUtils.applySpans(text, spans);
|
||||
// Detect entity support
|
||||
linkify.applyAllLinks(text, accountKey, false, true);
|
||||
textView.setText(text);
|
||||
|
Loading…
x
Reference in New Issue
Block a user