trying thumbor integration
improving quoted status support
This commit is contained in:
parent
5288fe34e9
commit
b181bbe38f
|
@ -30,275 +30,281 @@ import static org.mariotaku.twidere.annotation.Preference.Type.STRING;
|
|||
|
||||
public interface SharedPreferenceConstants {
|
||||
|
||||
public static final String FORMAT_PATTERN_TITLE = "[TITLE]";
|
||||
public static final String FORMAT_PATTERN_TEXT = "[TEXT]";
|
||||
public static final String FORMAT_PATTERN_NAME = "[NAME]";
|
||||
public static final String FORMAT_PATTERN_LINK = "[LINK]";
|
||||
String FORMAT_PATTERN_TITLE = "[TITLE]";
|
||||
String FORMAT_PATTERN_TEXT = "[TEXT]";
|
||||
String FORMAT_PATTERN_NAME = "[NAME]";
|
||||
String FORMAT_PATTERN_LINK = "[LINK]";
|
||||
|
||||
public static final String VALUE_NONE = "none";
|
||||
public static final String VALUE_LINK_HIGHLIGHT_OPTION_NONE = VALUE_NONE;
|
||||
public static final String VALUE_LINK_HIGHLIGHT_OPTION_HIGHLIGHT = "highlight";
|
||||
public static final String VALUE_LINK_HIGHLIGHT_OPTION_UNDERLINE = "underline";
|
||||
public static final String VALUE_LINK_HIGHLIGHT_OPTION_BOTH = "both";
|
||||
public static final int VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE = 0x0;
|
||||
public static final int VALUE_LINK_HIGHLIGHT_OPTION_CODE_HIGHLIGHT = 0x1;
|
||||
public static final int VALUE_LINK_HIGHLIGHT_OPTION_CODE_UNDERLINE = 0x2;
|
||||
public static final int VALUE_LINK_HIGHLIGHT_OPTION_CODE_BOTH = VALUE_LINK_HIGHLIGHT_OPTION_CODE_HIGHLIGHT
|
||||
String VALUE_NONE = "none";
|
||||
String VALUE_LINK_HIGHLIGHT_OPTION_NONE = VALUE_NONE;
|
||||
String VALUE_LINK_HIGHLIGHT_OPTION_HIGHLIGHT = "highlight";
|
||||
String VALUE_LINK_HIGHLIGHT_OPTION_UNDERLINE = "underline";
|
||||
String VALUE_LINK_HIGHLIGHT_OPTION_BOTH = "both";
|
||||
int VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE = 0x0;
|
||||
int VALUE_LINK_HIGHLIGHT_OPTION_CODE_HIGHLIGHT = 0x1;
|
||||
int VALUE_LINK_HIGHLIGHT_OPTION_CODE_UNDERLINE = 0x2;
|
||||
int VALUE_LINK_HIGHLIGHT_OPTION_CODE_BOTH = VALUE_LINK_HIGHLIGHT_OPTION_CODE_HIGHLIGHT
|
||||
| VALUE_LINK_HIGHLIGHT_OPTION_CODE_UNDERLINE;
|
||||
|
||||
public static final String VALUE_MEDIA_PREVIEW_STYLE_CROP = "crop";
|
||||
public static final String VALUE_MEDIA_PREVIEW_STYLE_SCALE = "scale";
|
||||
public static final String VALUE_MEDIA_PREVIEW_STYLE_NONE = VALUE_NONE;
|
||||
String VALUE_MEDIA_PREVIEW_STYLE_CROP = "crop";
|
||||
String VALUE_MEDIA_PREVIEW_STYLE_SCALE = "scale";
|
||||
String VALUE_MEDIA_PREVIEW_STYLE_NONE = VALUE_NONE;
|
||||
|
||||
public static final int VALUE_MEDIA_PREVIEW_STYLE_CODE_CROP = 1;
|
||||
public static final int VALUE_MEDIA_PREVIEW_STYLE_CODE_SCALE = 2;
|
||||
public static final int VALUE_MEDIA_PREVIEW_STYLE_CODE_NONE = 0;
|
||||
int VALUE_MEDIA_PREVIEW_STYLE_CODE_CROP = 1;
|
||||
int VALUE_MEDIA_PREVIEW_STYLE_CODE_SCALE = 2;
|
||||
int VALUE_MEDIA_PREVIEW_STYLE_CODE_NONE = 0;
|
||||
|
||||
public static final String VALUE_THEME_FONT_FAMILY_REGULAR = "sans-serif";
|
||||
public static final String VALUE_THEME_FONT_FAMILY_CONDENSED = "sans-serif-condensed";
|
||||
public static final String VALUE_THEME_FONT_FAMILY_LIGHT = "sans-serif-light";
|
||||
public static final String VALUE_THEME_FONT_FAMILY_THIN = "sans-serif-thin";
|
||||
String VALUE_THEME_FONT_FAMILY_REGULAR = "sans-serif";
|
||||
String VALUE_THEME_FONT_FAMILY_CONDENSED = "sans-serif-condensed";
|
||||
String VALUE_THEME_FONT_FAMILY_LIGHT = "sans-serif-light";
|
||||
String VALUE_THEME_FONT_FAMILY_THIN = "sans-serif-thin";
|
||||
|
||||
public static final int VALUE_NOTIFICATION_FLAG_NONE = 0x0;
|
||||
public static final int VALUE_NOTIFICATION_FLAG_RINGTONE = 0x1;
|
||||
public static final int VALUE_NOTIFICATION_FLAG_VIBRATION = 0x2;
|
||||
public static final int VALUE_NOTIFICATION_FLAG_LIGHT = 0x4;
|
||||
int VALUE_NOTIFICATION_FLAG_NONE = 0x0;
|
||||
int VALUE_NOTIFICATION_FLAG_RINGTONE = 0x1;
|
||||
int VALUE_NOTIFICATION_FLAG_VIBRATION = 0x2;
|
||||
int VALUE_NOTIFICATION_FLAG_LIGHT = 0x4;
|
||||
|
||||
public static final String VALUE_COMPOSE_QUIT_ACTION_ASK = "ask";
|
||||
public static final String VALUE_COMPOSE_QUIT_ACTION_SAVE = "save";
|
||||
public static final String VALUE_COMPOSE_QUIT_ACTION_DISCARD = "discard";
|
||||
String VALUE_COMPOSE_QUIT_ACTION_ASK = "ask";
|
||||
String VALUE_COMPOSE_QUIT_ACTION_SAVE = "save";
|
||||
String VALUE_COMPOSE_QUIT_ACTION_DISCARD = "discard";
|
||||
|
||||
public static final String VALUE_TAB_DIPLAY_OPTION_ICON = "icon";
|
||||
public static final String VALUE_TAB_DIPLAY_OPTION_LABEL = "label";
|
||||
public static final String VALUE_TAB_DIPLAY_OPTION_BOTH = "both";
|
||||
public static final int VALUE_TAB_DIPLAY_OPTION_CODE_ICON = 0x1;
|
||||
public static final int VALUE_TAB_DIPLAY_OPTION_CODE_LABEL = 0x2;
|
||||
public static final int VALUE_TAB_DIPLAY_OPTION_CODE_BOTH = VALUE_TAB_DIPLAY_OPTION_CODE_ICON
|
||||
String VALUE_TAB_DIPLAY_OPTION_ICON = "icon";
|
||||
String VALUE_TAB_DIPLAY_OPTION_LABEL = "label";
|
||||
String VALUE_TAB_DIPLAY_OPTION_BOTH = "both";
|
||||
int VALUE_TAB_DIPLAY_OPTION_CODE_ICON = 0x1;
|
||||
int VALUE_TAB_DIPLAY_OPTION_CODE_LABEL = 0x2;
|
||||
int VALUE_TAB_DIPLAY_OPTION_CODE_BOTH = VALUE_TAB_DIPLAY_OPTION_CODE_ICON
|
||||
| VALUE_TAB_DIPLAY_OPTION_CODE_LABEL;
|
||||
|
||||
public static final String VALUE_THEME_BACKGROUND_DEFAULT = "default";
|
||||
public static final String VALUE_THEME_BACKGROUND_SOLID = "solid";
|
||||
public static final String VALUE_THEME_BACKGROUND_TRANSPARENT = "transparent";
|
||||
String VALUE_THEME_BACKGROUND_DEFAULT = "default";
|
||||
String VALUE_THEME_BACKGROUND_SOLID = "solid";
|
||||
String VALUE_THEME_BACKGROUND_TRANSPARENT = "transparent";
|
||||
|
||||
public static final String VALUE_THEME_NAME_TWIDERE = "twidere";
|
||||
public static final String VALUE_THEME_NAME_DARK = "dark";
|
||||
public static final String VALUE_THEME_NAME_LIGHT = "light";
|
||||
String VALUE_THEME_NAME_TWIDERE = "twidere";
|
||||
String VALUE_THEME_NAME_DARK = "dark";
|
||||
String VALUE_THEME_NAME_LIGHT = "light";
|
||||
|
||||
public static final String VALUE_PROFILE_IMAGE_STYLE_ROUND = "round";
|
||||
public static final String VALUE_PROFILE_IMAGE_STYLE_SQUARE = "square";
|
||||
String VALUE_PROFILE_IMAGE_STYLE_ROUND = "round";
|
||||
String VALUE_PROFILE_IMAGE_STYLE_SQUARE = "square";
|
||||
|
||||
public static final String VALUE_COMPOSE_NOW_ACTION_COMPOSE = "compose";
|
||||
public static final String VALUE_COMPOSE_NOW_ACTION_TAKE_PHOTO = "take_photo";
|
||||
public static final String VALUE_COMPOSE_NOW_ACTION_PICK_IMAGE = "pick_image";
|
||||
String VALUE_COMPOSE_NOW_ACTION_COMPOSE = "compose";
|
||||
String VALUE_COMPOSE_NOW_ACTION_TAKE_PHOTO = "take_photo";
|
||||
String VALUE_COMPOSE_NOW_ACTION_PICK_IMAGE = "pick_image";
|
||||
|
||||
public static final String VALUE_CARD_HIGHLIGHT_OPTION_NONE = VALUE_NONE;
|
||||
public static final String VALUE_CARD_HIGHLIGHT_OPTION_BACKGROUND = "background";
|
||||
public static final String VALUE_CARD_HIGHLIGHT_OPTION_LINE = "line";
|
||||
String VALUE_CARD_HIGHLIGHT_OPTION_NONE = VALUE_NONE;
|
||||
String VALUE_CARD_HIGHLIGHT_OPTION_BACKGROUND = "background";
|
||||
String VALUE_CARD_HIGHLIGHT_OPTION_LINE = "line";
|
||||
|
||||
public static final int VALUE_CARD_HIGHLIGHT_OPTION_CODE_NONE = 0x0;
|
||||
public static final int VALUE_CARD_HIGHLIGHT_OPTION_CODE_BACKGROUND = 0x1;
|
||||
public static final int VALUE_CARD_HIGHLIGHT_OPTION_CODE_LINE = 0x2;
|
||||
int VALUE_CARD_HIGHLIGHT_OPTION_CODE_NONE = 0x0;
|
||||
int VALUE_CARD_HIGHLIGHT_OPTION_CODE_BACKGROUND = 0x1;
|
||||
int VALUE_CARD_HIGHLIGHT_OPTION_CODE_LINE = 0x2;
|
||||
|
||||
public static final String DEFAULT_THEME = VALUE_THEME_NAME_TWIDERE;
|
||||
public static final String DEFAULT_THEME_BACKGROUND = VALUE_THEME_BACKGROUND_DEFAULT;
|
||||
public static final String DEFAULT_THEME_FONT_FAMILY = VALUE_THEME_FONT_FAMILY_REGULAR;
|
||||
public static final int DEFAULT_THEME_BACKGROUND_ALPHA = 160;
|
||||
String DEFAULT_THEME = VALUE_THEME_NAME_TWIDERE;
|
||||
String DEFAULT_THEME_BACKGROUND = VALUE_THEME_BACKGROUND_DEFAULT;
|
||||
String DEFAULT_THEME_FONT_FAMILY = VALUE_THEME_FONT_FAMILY_REGULAR;
|
||||
int DEFAULT_THEME_BACKGROUND_ALPHA = 160;
|
||||
|
||||
public static final String DEFAULT_QUOTE_FORMAT = "RT @" + FORMAT_PATTERN_NAME + ": " + FORMAT_PATTERN_TEXT;
|
||||
public static final String DEFAULT_SHARE_FORMAT = FORMAT_PATTERN_TITLE + " - " + FORMAT_PATTERN_TEXT;
|
||||
public static final String DEFAULT_IMAGE_UPLOAD_FORMAT = FORMAT_PATTERN_TEXT + " " + FORMAT_PATTERN_LINK;
|
||||
String DEFAULT_QUOTE_FORMAT = "RT @" + FORMAT_PATTERN_NAME + ": " + FORMAT_PATTERN_TEXT;
|
||||
String DEFAULT_SHARE_FORMAT = FORMAT_PATTERN_TITLE + " - " + FORMAT_PATTERN_TEXT;
|
||||
String DEFAULT_IMAGE_UPLOAD_FORMAT = FORMAT_PATTERN_TEXT + " " + FORMAT_PATTERN_LINK;
|
||||
|
||||
public static final String DEFAULT_REFRESH_INTERVAL = "15";
|
||||
public static final boolean DEFAULT_AUTO_REFRESH = true;
|
||||
public static final boolean DEFAULT_AUTO_REFRESH_HOME_TIMELINE = false;
|
||||
public static final boolean DEFAULT_AUTO_REFRESH_MENTIONS = true;
|
||||
public static final boolean DEFAULT_AUTO_REFRESH_DIRECT_MESSAGES = true;
|
||||
public static final boolean DEFAULT_AUTO_REFRESH_TRENDS = false;
|
||||
public static final boolean DEFAULT_NOTIFICATION = true;
|
||||
public static final int DEFAULT_NOTIFICATION_TYPE_HOME = VALUE_NOTIFICATION_FLAG_NONE;
|
||||
public static final int DEFAULT_NOTIFICATION_TYPE_MENTIONS = VALUE_NOTIFICATION_FLAG_VIBRATION
|
||||
String DEFAULT_REFRESH_INTERVAL = "15";
|
||||
boolean DEFAULT_AUTO_REFRESH = true;
|
||||
boolean DEFAULT_AUTO_REFRESH_HOME_TIMELINE = false;
|
||||
boolean DEFAULT_AUTO_REFRESH_MENTIONS = true;
|
||||
boolean DEFAULT_AUTO_REFRESH_DIRECT_MESSAGES = true;
|
||||
boolean DEFAULT_AUTO_REFRESH_TRENDS = false;
|
||||
boolean DEFAULT_NOTIFICATION = true;
|
||||
int DEFAULT_NOTIFICATION_TYPE_HOME = VALUE_NOTIFICATION_FLAG_NONE;
|
||||
int DEFAULT_NOTIFICATION_TYPE_MENTIONS = VALUE_NOTIFICATION_FLAG_VIBRATION
|
||||
| VALUE_NOTIFICATION_FLAG_LIGHT;
|
||||
public static final int DEFAULT_NOTIFICATION_TYPE_DIRECT_MESSAGES = VALUE_NOTIFICATION_FLAG_RINGTONE
|
||||
int DEFAULT_NOTIFICATION_TYPE_DIRECT_MESSAGES = VALUE_NOTIFICATION_FLAG_RINGTONE
|
||||
| VALUE_NOTIFICATION_FLAG_VIBRATION | VALUE_NOTIFICATION_FLAG_LIGHT;
|
||||
|
||||
public static final boolean DEFAULT_HOME_TIMELINE_NOTIFICATION = false;
|
||||
public static final boolean DEFAULT_MENTIONS_NOTIFICATION = true;
|
||||
public static final boolean DEFAULT_DIRECT_MESSAGES_NOTIFICATION = true;
|
||||
boolean DEFAULT_HOME_TIMELINE_NOTIFICATION = false;
|
||||
boolean DEFAULT_MENTIONS_NOTIFICATION = true;
|
||||
boolean DEFAULT_DIRECT_MESSAGES_NOTIFICATION = true;
|
||||
|
||||
public static final int DEFAULT_DATABASE_ITEM_LIMIT = 100;
|
||||
public static final int DEFAULT_LOAD_ITEM_LIMIT = 20;
|
||||
public static final String DEFAULT_CARD_HIGHLIGHT_OPTION = VALUE_CARD_HIGHLIGHT_OPTION_BACKGROUND;
|
||||
int DEFAULT_DATABASE_ITEM_LIMIT = 100;
|
||||
int DEFAULT_LOAD_ITEM_LIMIT = 20;
|
||||
String DEFAULT_CARD_HIGHLIGHT_OPTION = VALUE_CARD_HIGHLIGHT_OPTION_BACKGROUND;
|
||||
|
||||
@Preference(type = INT, hasDefault = true, defaultInt = DEFAULT_DATABASE_ITEM_LIMIT)
|
||||
public static final String KEY_DATABASE_ITEM_LIMIT = "database_item_limit";
|
||||
String KEY_DATABASE_ITEM_LIMIT = "database_item_limit";
|
||||
@Preference(type = INT, hasDefault = true, defaultInt = DEFAULT_LOAD_ITEM_LIMIT)
|
||||
public static final String KEY_LOAD_ITEM_LIMIT = "load_item_limit";
|
||||
String KEY_LOAD_ITEM_LIMIT = "load_item_limit";
|
||||
@Preference(type = INT, hasDefault = true, defaultInt = 15)
|
||||
public static final String KEY_TEXT_SIZE = "text_size_int";
|
||||
String KEY_TEXT_SIZE = "text_size_int";
|
||||
@Preference(type = STRING, hasDefault = true, defaultString = DEFAULT_THEME)
|
||||
public static final String KEY_THEME = "theme";
|
||||
String KEY_THEME = "theme";
|
||||
@Preference(type = STRING, hasDefault = true, defaultString = DEFAULT_THEME_BACKGROUND)
|
||||
public static final String KEY_THEME_BACKGROUND = "theme_background";
|
||||
String KEY_THEME_BACKGROUND = "theme_background";
|
||||
@Preference(type = INT, hasDefault = true, defaultInt = DEFAULT_THEME_BACKGROUND_ALPHA)
|
||||
public static final String KEY_THEME_BACKGROUND_ALPHA = "theme_background_alpha";
|
||||
String KEY_THEME_BACKGROUND_ALPHA = "theme_background_alpha";
|
||||
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = true)
|
||||
public static final String KEY_THEME_DARK_ACTIONBAR = "theme_dark_actionbar";
|
||||
String KEY_THEME_DARK_ACTIONBAR = "theme_dark_actionbar";
|
||||
@Preference(type = INT)
|
||||
public static final String KEY_THEME_COLOR = "theme_color";
|
||||
String KEY_THEME_COLOR = "theme_color";
|
||||
@Preference(type = STRING, hasDefault = true, defaultString = DEFAULT_THEME_FONT_FAMILY)
|
||||
public static final String KEY_THEME_FONT_FAMILY = "theme_font_family";
|
||||
String KEY_THEME_FONT_FAMILY = "theme_font_family";
|
||||
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = true)
|
||||
public static final String KEY_DISPLAY_PROFILE_IMAGE = "display_profile_image";
|
||||
String KEY_DISPLAY_PROFILE_IMAGE = "display_profile_image";
|
||||
@Preference(type = BOOLEAN)
|
||||
public static final String KEY_LEFTSIDE_COMPOSE_BUTTON = "leftside_compose_button";
|
||||
String KEY_LEFTSIDE_COMPOSE_BUTTON = "leftside_compose_button";
|
||||
@Preference(type = BOOLEAN)
|
||||
public static final String KEY_ATTACH_LOCATION = "attach_location";
|
||||
String KEY_ATTACH_LOCATION = "attach_location";
|
||||
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = true)
|
||||
public static final String KEY_GZIP_COMPRESSING = "gzip_compressing";
|
||||
String KEY_GZIP_COMPRESSING = "gzip_compressing";
|
||||
@Preference(type = BOOLEAN)
|
||||
public static final String KEY_IGNORE_SSL_ERROR = "ignore_ssl_error";
|
||||
String KEY_IGNORE_SSL_ERROR = "ignore_ssl_error";
|
||||
@Preference(type = BOOLEAN)
|
||||
public static final String KEY_LOAD_MORE_AUTOMATICALLY = "load_more_automatically";
|
||||
String KEY_LOAD_MORE_AUTOMATICALLY = "load_more_automatically";
|
||||
@Preference(type = STRING)
|
||||
public static final String KEY_QUOTE_FORMAT = "quote_format";
|
||||
String KEY_QUOTE_FORMAT = "quote_format";
|
||||
@Preference(type = BOOLEAN)
|
||||
public static final String KEY_REMEMBER_POSITION = "remember_position";
|
||||
String KEY_REMEMBER_POSITION = "remember_position";
|
||||
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
|
||||
public static final String KEY_READ_FROM_BOTTOM = "read_from_bottom";
|
||||
String KEY_READ_FROM_BOTTOM = "read_from_bottom";
|
||||
@Preference(type = INT, exportable = false)
|
||||
public static final String KEY_SAVED_TAB_POSITION = "saved_tab_position";
|
||||
String KEY_SAVED_TAB_POSITION = "saved_tab_position";
|
||||
@Preference(type = BOOLEAN)
|
||||
public static final String KEY_ENABLE_PROXY = "enable_proxy";
|
||||
String KEY_ENABLE_PROXY = "enable_proxy";
|
||||
@Preference(type = STRING)
|
||||
public static final String KEY_PROXY_HOST = "proxy_host";
|
||||
String KEY_PROXY_HOST = "proxy_host";
|
||||
@Preference(type = STRING)
|
||||
public static final String KEY_PROXY_PORT = "proxy_port";
|
||||
String KEY_PROXY_PORT = "proxy_port";
|
||||
@Preference(type = BOOLEAN)
|
||||
public static final String KEY_REFRESH_ON_START = "refresh_on_start";
|
||||
String KEY_REFRESH_ON_START = "refresh_on_start";
|
||||
@Preference(type = BOOLEAN)
|
||||
public static final String KEY_REFRESH_AFTER_TWEET = "refresh_after_tweet";
|
||||
String KEY_REFRESH_AFTER_TWEET = "refresh_after_tweet";
|
||||
@Preference(type = BOOLEAN)
|
||||
public static final String KEY_AUTO_REFRESH = "auto_refresh";
|
||||
String KEY_AUTO_REFRESH = "auto_refresh";
|
||||
@Preference(type = STRING)
|
||||
public static final String KEY_REFRESH_INTERVAL = "refresh_interval";
|
||||
String KEY_REFRESH_INTERVAL = "refresh_interval";
|
||||
@Preference(type = BOOLEAN)
|
||||
public static final String KEY_AUTO_REFRESH_HOME_TIMELINE = "auto_refresh_home_timeline";
|
||||
String KEY_AUTO_REFRESH_HOME_TIMELINE = "auto_refresh_home_timeline";
|
||||
@Preference(type = BOOLEAN)
|
||||
public static final String KEY_AUTO_REFRESH_MENTIONS = "auto_refresh_mentions";
|
||||
String KEY_AUTO_REFRESH_MENTIONS = "auto_refresh_mentions";
|
||||
@Preference(type = BOOLEAN)
|
||||
public static final String KEY_AUTO_REFRESH_DIRECT_MESSAGES = "auto_refresh_direct_messages";
|
||||
String KEY_AUTO_REFRESH_DIRECT_MESSAGES = "auto_refresh_direct_messages";
|
||||
@Preference(type = BOOLEAN)
|
||||
public static final String KEY_AUTO_REFRESH_TRENDS = "auto_refresh_trends";
|
||||
String KEY_AUTO_REFRESH_TRENDS = "auto_refresh_trends";
|
||||
@Preference(type = BOOLEAN)
|
||||
public static final String KEY_HOME_TIMELINE_NOTIFICATION = "home_timeline_notification";
|
||||
String KEY_HOME_TIMELINE_NOTIFICATION = "home_timeline_notification";
|
||||
@Preference(type = BOOLEAN)
|
||||
public static final String KEY_MENTIONS_NOTIFICATION = "mentions_notification";
|
||||
String KEY_MENTIONS_NOTIFICATION = "mentions_notification";
|
||||
@Preference(type = BOOLEAN)
|
||||
public static final String KEY_DIRECT_MESSAGES_NOTIFICATION = "direct_messages_notification";
|
||||
String KEY_DIRECT_MESSAGES_NOTIFICATION = "direct_messages_notification";
|
||||
@Preference(type = INT)
|
||||
public static final String KEY_LOCAL_TRENDS_WOEID = "local_trends_woeid";
|
||||
public static final String KEY_NOTIFICATION_RINGTONE = "notification_ringtone";
|
||||
public static final String KEY_NOTIFICATION_LIGHT_COLOR = "notification_light_color";
|
||||
public static final String KEY_SHARE_FORMAT = "share_format";
|
||||
public static final String KEY_HOME_REFRESH_MENTIONS = "home_refresh_mentions";
|
||||
public static final String KEY_HOME_REFRESH_DIRECT_MESSAGES = "home_refresh_direct_messages";
|
||||
public static final String KEY_HOME_REFRESH_TRENDS = "home_refresh_trends";
|
||||
public static final String KEY_IMAGE_UPLOAD_FORMAT = "image_upload_format";
|
||||
public static final String KEY_STATUS_SHORTENER = "status_shortener";
|
||||
public static final String KEY_MEDIA_UPLOADER = "media_uploader";
|
||||
String KEY_LOCAL_TRENDS_WOEID = "local_trends_woeid";
|
||||
String KEY_NOTIFICATION_RINGTONE = "notification_ringtone";
|
||||
String KEY_NOTIFICATION_LIGHT_COLOR = "notification_light_color";
|
||||
String KEY_SHARE_FORMAT = "share_format";
|
||||
String KEY_HOME_REFRESH_MENTIONS = "home_refresh_mentions";
|
||||
String KEY_HOME_REFRESH_DIRECT_MESSAGES = "home_refresh_direct_messages";
|
||||
String KEY_HOME_REFRESH_TRENDS = "home_refresh_trends";
|
||||
String KEY_IMAGE_UPLOAD_FORMAT = "image_upload_format";
|
||||
String KEY_STATUS_SHORTENER = "status_shortener";
|
||||
String KEY_MEDIA_UPLOADER = "media_uploader";
|
||||
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
|
||||
public static final String KEY_SHOW_ABSOLUTE_TIME = "show_absolute_time";
|
||||
String KEY_SHOW_ABSOLUTE_TIME = "show_absolute_time";
|
||||
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
|
||||
public static final String KEY_QUICK_SEND = "quick_send";
|
||||
String KEY_QUICK_SEND = "quick_send";
|
||||
@Preference(type = STRING, exportable = false)
|
||||
public static final String KEY_COMPOSE_ACCOUNTS = "compose_accounts";
|
||||
String KEY_COMPOSE_ACCOUNTS = "compose_accounts";
|
||||
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
|
||||
public static final String KEY_TCP_DNS_QUERY = "tcp_dns_query";
|
||||
String KEY_TCP_DNS_QUERY = "tcp_dns_query";
|
||||
@Preference(type = STRING, hasDefault = true, defaultString = "8.8.8.8")
|
||||
public static final String KEY_DNS_SERVER = "dns_server";
|
||||
public static final String KEY_CONNECTION_TIMEOUT = "connection_timeout";
|
||||
String KEY_DNS_SERVER = "dns_server";
|
||||
String KEY_CONNECTION_TIMEOUT = "connection_timeout";
|
||||
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = true)
|
||||
public static final String KEY_NAME_FIRST = "name_first";
|
||||
public static final String KEY_STOP_AUTO_REFRESH_WHEN_BATTERY_LOW = "stop_auto_refresh_when_battery_low";
|
||||
String KEY_NAME_FIRST = "name_first";
|
||||
String KEY_STOP_AUTO_REFRESH_WHEN_BATTERY_LOW = "stop_auto_refresh_when_battery_low";
|
||||
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
|
||||
public static final String KEY_DISPLAY_SENSITIVE_CONTENTS = "display_sensitive_contents";
|
||||
String KEY_DISPLAY_SENSITIVE_CONTENTS = "display_sensitive_contents";
|
||||
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = true)
|
||||
public static final String KEY_PHISHING_LINK_WARNING = "phishing_link_warning";
|
||||
String KEY_PHISHING_LINK_WARNING = "phishing_link_warning";
|
||||
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
|
||||
public static final String KEY_FAST_SCROLL_THUMB = "fast_scroll_thumb";
|
||||
public static final String KEY_LINK_HIGHLIGHT_OPTION = "link_highlight_option";
|
||||
String KEY_FAST_SCROLL_THUMB = "fast_scroll_thumb";
|
||||
String KEY_LINK_HIGHLIGHT_OPTION = "link_highlight_option";
|
||||
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = true)
|
||||
public static final String KEY_INDICATE_MY_STATUS = "indicate_my_status";
|
||||
public static final String KEY_PRELOAD_PROFILE_IMAGES = "preload_profile_images";
|
||||
public static final String KEY_PRELOAD_PREVIEW_IMAGES = "preload_preview_images";
|
||||
String KEY_INDICATE_MY_STATUS = "indicate_my_status";
|
||||
String KEY_PRELOAD_PROFILE_IMAGES = "preload_profile_images";
|
||||
String KEY_PRELOAD_PREVIEW_IMAGES = "preload_preview_images";
|
||||
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = true)
|
||||
public static final String KEY_PRELOAD_WIFI_ONLY = "preload_wifi_only";
|
||||
String KEY_PRELOAD_WIFI_ONLY = "preload_wifi_only";
|
||||
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = true)
|
||||
public static final String KEY_LINK_TO_QUOTED_TWEET = "link_to_quoted_tweet";
|
||||
String KEY_LINK_TO_QUOTED_TWEET = "link_to_quoted_tweet";
|
||||
@Preference(type = BOOLEAN)
|
||||
public static final String KEY_BACKGROUND_TOAST_NOTIFICATION = "background_toast_notification";
|
||||
String KEY_BACKGROUND_TOAST_NOTIFICATION = "background_toast_notification";
|
||||
@Preference(type = STRING)
|
||||
public static final String KEY_COMPOSE_QUIT_ACTION = "compose_quit_action";
|
||||
String KEY_COMPOSE_QUIT_ACTION = "compose_quit_action";
|
||||
@Preference(type = BOOLEAN)
|
||||
public static final String KEY_NO_CLOSE_AFTER_TWEET_SENT = "no_close_after_tweet_sent";
|
||||
String KEY_NO_CLOSE_AFTER_TWEET_SENT = "no_close_after_tweet_sent";
|
||||
@Preference(type = BOOLEAN)
|
||||
public static final String KEY_FAST_IMAGE_LOADING = "fast_image_loading";
|
||||
String KEY_FAST_IMAGE_LOADING = "fast_image_loading";
|
||||
@Preference(type = STRING, hasDefault = false)
|
||||
public static final String KEY_API_URL_FORMAT = "api_url_format";
|
||||
String KEY_API_URL_FORMAT = "api_url_format";
|
||||
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
|
||||
public static final String KEY_SAME_OAUTH_SIGNING_URL = "same_oauth_signing_url";
|
||||
String KEY_SAME_OAUTH_SIGNING_URL = "same_oauth_signing_url";
|
||||
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
|
||||
public static final String KEY_NO_VERSION_SUFFIX = "no_version_suffix";
|
||||
String KEY_NO_VERSION_SUFFIX = "no_version_suffix";
|
||||
@Preference(type = INT, hasDefault = true, defaultInt = Accounts.AUTH_TYPE_OAUTH)
|
||||
public static final String KEY_AUTH_TYPE = "auth_type";
|
||||
String KEY_AUTH_TYPE = "auth_type";
|
||||
@Preference(type = STRING, hasDefault = true, defaultString = TwidereConstants.TWITTER_CONSUMER_KEY_3)
|
||||
public static final String KEY_CONSUMER_KEY = "consumer_key";
|
||||
String KEY_CONSUMER_KEY = "consumer_key";
|
||||
@Preference(type = STRING, hasDefault = true, defaultString = TwidereConstants.TWITTER_CONSUMER_SECRET_3)
|
||||
public static final String KEY_CONSUMER_SECRET = "consumer_secret";
|
||||
public static final String KEY_FILTERS_IN_HOME_TIMELINE = "filters_in_home_timeline";
|
||||
public static final String KEY_FILTERS_IN_MENTIONS_TIMELINE = "filters_in_mentions";
|
||||
public static final String KEY_FILTERS_FOR_RTS = "filters_for_rts";
|
||||
public static final String KEY_SETTINGS_WIZARD_COMPLETED = "settings_wizard_completed";
|
||||
String KEY_CONSUMER_SECRET = "consumer_secret";
|
||||
String KEY_FILTERS_IN_HOME_TIMELINE = "filters_in_home_timeline";
|
||||
String KEY_FILTERS_IN_MENTIONS_TIMELINE = "filters_in_mentions";
|
||||
String KEY_FILTERS_FOR_RTS = "filters_for_rts";
|
||||
String KEY_SETTINGS_WIZARD_COMPLETED = "settings_wizard_completed";
|
||||
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = true)
|
||||
public static final String KEY_CARD_ANIMATION = "card_animation";
|
||||
public static final String KEY_UNREAD_COUNT = "unread_count";
|
||||
public static final String KEY_NOTIFICATION = "notification";
|
||||
public static final String KEY_NOTIFICATION_TYPE_HOME = "notification_type_home";
|
||||
public static final String KEY_NOTIFICATION_TYPE_MENTIONS = "notification_type_mentions";
|
||||
public static final String KEY_NOTIFICATION_TYPE_DIRECT_MESSAGES = "notification_type_direct_messages";
|
||||
public static final String KEY_NOTIFICATION_FOLLOWING_ONLY = "notification_following_only";
|
||||
String KEY_CARD_ANIMATION = "card_animation";
|
||||
String KEY_UNREAD_COUNT = "unread_count";
|
||||
String KEY_NOTIFICATION = "notification";
|
||||
String KEY_NOTIFICATION_TYPE_HOME = "notification_type_home";
|
||||
String KEY_NOTIFICATION_TYPE_MENTIONS = "notification_type_mentions";
|
||||
String KEY_NOTIFICATION_TYPE_DIRECT_MESSAGES = "notification_type_direct_messages";
|
||||
String KEY_NOTIFICATION_FOLLOWING_ONLY = "notification_following_only";
|
||||
|
||||
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
|
||||
public static final String KEY_COMPACT_CARDS = "compact_cards";
|
||||
String KEY_COMPACT_CARDS = "compact_cards";
|
||||
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
|
||||
public static final String KEY_FORCE_USING_PRIVATE_APIS = "force_using_private_apis";
|
||||
String KEY_FORCE_USING_PRIVATE_APIS = "force_using_private_apis";
|
||||
@Preference(type = STRING, hasDefault = true, defaultString = "140")
|
||||
public static final String KEY_STATUS_TEXT_LIMIT = "status_text_limit";
|
||||
String KEY_STATUS_TEXT_LIMIT = "status_text_limit";
|
||||
@Preference(type = STRING, hasDefault = true, defaultString = VALUE_COMPOSE_NOW_ACTION_COMPOSE)
|
||||
public static final String KEY_COMPOSE_NOW_ACTION = "compose_now_action";
|
||||
public static final String KEY_FALLBACK_TWITTER_LINK_HANDLER = "fallback_twitter_link_handler";
|
||||
String KEY_COMPOSE_NOW_ACTION = "compose_now_action";
|
||||
String KEY_FALLBACK_TWITTER_LINK_HANDLER = "fallback_twitter_link_handler";
|
||||
|
||||
@Preference(type = STRING, hasDefault = true, defaultString = VALUE_MEDIA_PREVIEW_STYLE_CROP)
|
||||
public static final String KEY_MEDIA_PREVIEW_STYLE = "media_preview_style";
|
||||
String KEY_MEDIA_PREVIEW_STYLE = "media_preview_style";
|
||||
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
|
||||
public static final String KEY_MEDIA_PREVIEW = "media_preview";
|
||||
String KEY_MEDIA_PREVIEW = "media_preview";
|
||||
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
|
||||
public static final String KEY_SORT_TIMELINE_BY_ID = "sort_timeline_by_id";
|
||||
String KEY_SORT_TIMELINE_BY_ID = "sort_timeline_by_id";
|
||||
@Preference(type = STRING, hasDefault = true)
|
||||
public static final String KEY_PROFILE_IMAGE_STYLE = "profile_image_style";
|
||||
String KEY_PROFILE_IMAGE_STYLE = "profile_image_style";
|
||||
|
||||
public static final String KEY_QUICK_MENU_EXPANDED = "quick_menu_expanded";
|
||||
String KEY_QUICK_MENU_EXPANDED = "quick_menu_expanded";
|
||||
|
||||
@Preference(type = STRING)
|
||||
public static final String KEY_TRANSLATION_DESTINATION = "translation_destination";
|
||||
String KEY_TRANSLATION_DESTINATION = "translation_destination";
|
||||
@Preference(type = STRING)
|
||||
public static final String KEY_TAB_DISPLAY_OPTION = "tab_display_option";
|
||||
String KEY_TAB_DISPLAY_OPTION = "tab_display_option";
|
||||
@Preference(type = STRING)
|
||||
public static final String KEY_CARD_HIGHLIGHT_OPTION = "card_highlight_option";
|
||||
String KEY_CARD_HIGHLIGHT_OPTION = "card_highlight_option";
|
||||
@Preference(type = INT, exportable = false)
|
||||
public static final String KEY_LIVE_WALLPAPER_SCALE = "live_wallpaper_scale";
|
||||
String KEY_LIVE_WALLPAPER_SCALE = "live_wallpaper_scale";
|
||||
@Preference(type = LONG, exportable = false)
|
||||
public static final String KEY_API_LAST_CHANGE = "api_last_change";
|
||||
String KEY_API_LAST_CHANGE = "api_last_change";
|
||||
@Preference(type = LONG, exportable = false)
|
||||
public static final String KEY_DEFAULT_ACCOUNT_ID = "default_account_id";
|
||||
String KEY_DEFAULT_ACCOUNT_ID = "default_account_id";
|
||||
|
||||
|
||||
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
|
||||
String KEY_THUMBOR_ENABLED = "thumbor_enabled";
|
||||
String KEY_THUMBOR_ADDRESS = "thumbor_address";
|
||||
String KEY_THUMBOR_SECURITY_KEY = "thumbor_security_key";
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
|||
};
|
||||
public final long id, account_id, timestamp, user_id, retweet_id, retweeted_by_id, retweet_timestamp,
|
||||
retweet_count, favorite_count, reply_count, descendent_reply_count, in_reply_to_status_id,
|
||||
in_reply_to_user_id, my_retweet_id;
|
||||
in_reply_to_user_id, my_retweet_id, quote_id, quote_timestamp, quoted_by_user_id;
|
||||
public static final Comparator<ParcelableStatus> REVERSE_ID_COMPARATOR = new Comparator<ParcelableStatus>() {
|
||||
|
||||
@Override
|
||||
|
@ -104,11 +104,12 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
|||
}
|
||||
};
|
||||
public final boolean is_gap, is_retweet, is_favorite, is_possibly_sensitive, user_is_following, user_is_protected,
|
||||
user_is_verified;
|
||||
user_is_verified, is_quote;
|
||||
|
||||
public final String retweeted_by_name, retweeted_by_screen_name, retweeted_by_profile_image,
|
||||
text_html, text_plain, user_name, user_screen_name, in_reply_to_name, in_reply_to_screen_name,
|
||||
source, user_profile_image_url, text_unescaped, card_name;
|
||||
source, user_profile_image_url, text_unescaped, card_name, quote_text_html, quote_text_plain,
|
||||
quote_text_unescaped, quoted_by_user_name, quoted_by_user_screen_name, quoted_by_user_profile_image;
|
||||
|
||||
public final ParcelableLocation location;
|
||||
|
||||
|
@ -159,6 +160,16 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
|||
mentions = SimpleValueSerializer.fromSerializedString(values.getAsString(Statuses.MENTIONS_LIST), ParcelableUserMention.SIMPLE_CREATOR);
|
||||
card = ParcelableCardEntity.fromJSONString(values.getAsString(Statuses.CARD));
|
||||
place_full_name = values.getAsString(Statuses.PLACE_FULL_NAME);
|
||||
is_quote = ContentValuesUtils.getAsBoolean(values, Statuses.IS_QUOTE, false);
|
||||
quote_id = ContentValuesUtils.getAsLong(values, Statuses.QUOTE_ID, -1);
|
||||
quote_timestamp = ContentValuesUtils.getAsLong(values, Statuses.QUOTE_TIMESTAMP, -1);
|
||||
quote_text_html = values.getAsString(Statuses.QUOTE_TEXT_HTML);
|
||||
quote_text_plain = values.getAsString(Statuses.QUOTE_TEXT_PLAIN);
|
||||
quote_text_unescaped = values.getAsString(Statuses.QUOTE_TEXT_UNESCAPED);
|
||||
quoted_by_user_id = ContentValuesUtils.getAsLong(values, Statuses.QUOTED_BY_USER_ID, -1);
|
||||
quoted_by_user_name = values.getAsString(Statuses.QUOTED_BY_USER_NAME);
|
||||
quoted_by_user_screen_name = values.getAsString(Statuses.QUOTED_BY_USER_SCREEN_NAME);
|
||||
quoted_by_user_profile_image = values.getAsString(Statuses.QUOTED_BY_USER_PROFILE_IMAGE);
|
||||
card_name = card != null ? card.name : null;
|
||||
}
|
||||
|
||||
|
@ -204,6 +215,16 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
|||
mentions = idx.mentions != -1 ? ParcelableUserMention.fromJSONString(c.getString(idx.mentions)) : null;
|
||||
card = idx.card != -1 ? ParcelableCardEntity.fromJSONString(c.getString(idx.card)) : null;
|
||||
place_full_name = idx.place_full_name != -1 ? c.getString(idx.place_full_name) : null;
|
||||
is_quote = idx.is_quote != -1 && c.getShort(idx.is_quote) == 1;
|
||||
quote_id = idx.quote_id != -1 ? c.getLong(idx.quote_id) : -1;
|
||||
quote_timestamp = idx.quote_timestamp != -1 ? c.getLong(idx.quote_timestamp) : -1;
|
||||
quoted_by_user_id = idx.quoted_by_user_id != -1 ? c.getLong(idx.quoted_by_user_id) : -1;
|
||||
quote_text_html = idx.quote_text_html != -1 ? c.getString(idx.quote_text_html) : null;
|
||||
quote_text_plain = idx.quote_text_plain != -1 ? c.getString(idx.quote_text_plain) : null;
|
||||
quote_text_unescaped = idx.quote_text_unescaped != -1 ? c.getString(idx.quote_text_unescaped) : null;
|
||||
quoted_by_user_name = idx.quoted_by_user_name != -1 ? c.getString(idx.quoted_by_user_name) : null;
|
||||
quoted_by_user_screen_name = idx.quoted_by_user_screen_name != -1 ? c.getString(idx.quoted_by_user_screen_name) : null;
|
||||
quoted_by_user_profile_image = idx.quoted_by_user_profile_image != -1 ? c.getString(idx.quoted_by_user_profile_image) : null;
|
||||
card_name = card != null ? card.name : null;
|
||||
}
|
||||
|
||||
|
@ -246,6 +267,16 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
|||
mentions = in.readParcelableArray("mentions", ParcelableUserMention.JSON_CREATOR);
|
||||
card = in.readParcelable("card", ParcelableCardEntity.JSON_CREATOR);
|
||||
place_full_name = in.readString("place_full_name");
|
||||
is_quote = in.readBoolean("is_quote");
|
||||
quote_id = in.readLong("quote_id");
|
||||
quote_text_html = in.readString("quote_text_html");
|
||||
quote_text_plain = in.readString("quote_text_plain");
|
||||
quote_text_unescaped = in.readString("quote_text_unescaped");
|
||||
quote_timestamp = in.readLong("quote_timestamp");
|
||||
quoted_by_user_id = in.readLong("quoted_by_user_id");
|
||||
quoted_by_user_name = in.readString("quoted_by_user_name");
|
||||
quoted_by_user_screen_name = in.readString("quoted_by_user_screen_name");
|
||||
quoted_by_user_profile_image = in.readString("quoted_by_user_profile_image");
|
||||
card_name = card != null ? card.name : null;
|
||||
}
|
||||
|
||||
|
@ -262,11 +293,11 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
|||
reply_count = in.readLong();
|
||||
descendent_reply_count = in.readLong();
|
||||
in_reply_to_status_id = in.readLong();
|
||||
is_gap = in.readInt() == 1;
|
||||
is_retweet = in.readInt() == 1;
|
||||
is_favorite = in.readInt() == 1;
|
||||
user_is_protected = in.readInt() == 1;
|
||||
user_is_verified = in.readInt() == 1;
|
||||
is_gap = in.readByte() == 1;
|
||||
is_retweet = in.readByte() == 1;
|
||||
is_favorite = in.readByte() == 1;
|
||||
user_is_protected = in.readByte() == 1;
|
||||
user_is_verified = in.readByte() == 1;
|
||||
retweeted_by_name = in.readString();
|
||||
retweeted_by_screen_name = in.readString();
|
||||
retweeted_by_profile_image = in.readString();
|
||||
|
@ -280,14 +311,24 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
|||
media = in.createTypedArray(ParcelableMedia.CREATOR);
|
||||
location = in.readParcelable(ParcelableLocation.class.getClassLoader());
|
||||
my_retweet_id = in.readLong();
|
||||
is_possibly_sensitive = in.readInt() == 1;
|
||||
user_is_following = in.readInt() == 1;
|
||||
is_possibly_sensitive = in.readByte() == 1;
|
||||
user_is_following = in.readByte() == 1;
|
||||
text_unescaped = in.readString();
|
||||
in_reply_to_user_id = in.readLong();
|
||||
in_reply_to_name = in.readString();
|
||||
mentions = in.createTypedArray(ParcelableUserMention.CREATOR);
|
||||
card = in.readParcelable(ParcelableCardEntity.class.getClassLoader());
|
||||
place_full_name = in.readString();
|
||||
is_quote = in.readByte() == 1;
|
||||
quote_id = in.readLong();
|
||||
quote_text_html = in.readString();
|
||||
quote_text_plain = in.readString();
|
||||
quote_text_unescaped = in.readString();
|
||||
quote_timestamp = in.readLong();
|
||||
quoted_by_user_id = in.readLong();
|
||||
quoted_by_user_name = in.readString();
|
||||
quoted_by_user_screen_name = in.readString();
|
||||
quoted_by_user_profile_image = in.readString();
|
||||
card_name = card != null ? card.name : null;
|
||||
}
|
||||
|
||||
|
@ -331,9 +372,119 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
|||
mentions = orig.mentions;
|
||||
card = orig.card;
|
||||
place_full_name = orig.place_full_name;
|
||||
is_quote = orig.is_quote;
|
||||
quote_id = orig.quote_id;
|
||||
quote_timestamp = orig.quote_timestamp;
|
||||
quoted_by_user_id = orig.quoted_by_user_id;
|
||||
quoted_by_user_name = orig.quoted_by_user_name;
|
||||
quoted_by_user_screen_name = orig.quoted_by_user_screen_name;
|
||||
quoted_by_user_profile_image = orig.quoted_by_user_profile_image;
|
||||
quote_text_html = orig.quote_text_html;
|
||||
quote_text_plain = orig.quote_text_plain;
|
||||
quote_text_unescaped = orig.quote_text_unescaped;
|
||||
card_name = card != null ? card.name : null;
|
||||
}
|
||||
|
||||
public ParcelableStatus(final Status orig, final long account_id, final boolean is_gap) {
|
||||
this.is_gap = is_gap;
|
||||
this.account_id = account_id;
|
||||
id = orig.getId();
|
||||
timestamp = getTime(orig.getCreatedAt());
|
||||
|
||||
final Status retweeted = orig.getRetweetedStatus();
|
||||
final User retweet_user = retweeted != null ? orig.getUser() : null;
|
||||
is_retweet = orig.isRetweet();
|
||||
retweet_id = retweeted != null ? retweeted.getId() : -1;
|
||||
retweet_timestamp = retweeted != null ? getTime(retweeted.getCreatedAt()) : -1;
|
||||
retweeted_by_id = retweet_user != null ? retweet_user.getId() : -1;
|
||||
retweeted_by_name = retweet_user != null ? retweet_user.getName() : null;
|
||||
retweeted_by_screen_name = retweet_user != null ? retweet_user.getScreenName() : null;
|
||||
retweeted_by_profile_image = retweet_user != null ?
|
||||
ParseUtils.parseString(retweet_user.getProfileImageUrlHttps()) : null;
|
||||
|
||||
final Status quoted = orig.getQuotedStatus();
|
||||
final User quote_user = quoted != null ? orig.getUser() : null;
|
||||
is_quote = orig.isQuote();
|
||||
quote_id = quoted != null ? quoted.getId() : -1;
|
||||
quote_text_html = TwitterContentUtils.formatStatusText(orig);
|
||||
quote_text_plain = orig.getText();
|
||||
quote_text_unescaped = HtmlEscapeHelper.toPlainText(quote_text_html);
|
||||
quote_timestamp = quoted != null ? quoted.getCreatedAt().getTime() : -1;
|
||||
quoted_by_user_id = quote_user != null ? quote_user.getId() : -1;
|
||||
quoted_by_user_name = quote_user != null ? quote_user.getName() : null;
|
||||
quoted_by_user_screen_name = quote_user != null ? quote_user.getScreenName() : null;
|
||||
quoted_by_user_profile_image = quote_user != null ? ParseUtils.parseString(quote_user.getProfileImageUrlHttps()) : null;
|
||||
|
||||
final Status status;
|
||||
if (quoted != null) {
|
||||
status = quoted;
|
||||
} else if (retweeted != null) {
|
||||
status = retweeted;
|
||||
} else {
|
||||
status = orig;
|
||||
}
|
||||
final User user = status.getUser();
|
||||
user_id = user.getId();
|
||||
user_name = user.getName();
|
||||
user_screen_name = user.getScreenName();
|
||||
user_profile_image_url = ParseUtils.parseString(user.getProfileImageUrlHttps());
|
||||
user_is_protected = user.isProtected();
|
||||
user_is_verified = user.isVerified();
|
||||
user_is_following = user.isFollowing();
|
||||
text_html = TwitterContentUtils.formatStatusText(status);
|
||||
media = ParcelableMedia.fromEntities(status);
|
||||
text_plain = status.getText();
|
||||
retweet_count = status.getRetweetCount();
|
||||
favorite_count = status.getFavoriteCount();
|
||||
reply_count = status.getReplyCount();
|
||||
descendent_reply_count = status.getDescendentReplyCount();
|
||||
in_reply_to_name = TwitterContentUtils.getInReplyToName(status);
|
||||
in_reply_to_screen_name = status.getInReplyToScreenName();
|
||||
in_reply_to_status_id = status.getInReplyToStatusId();
|
||||
in_reply_to_user_id = status.getInReplyToUserId();
|
||||
source = status.getSource();
|
||||
location = ParcelableLocation.fromGeoLocation(status.getGeoLocation());
|
||||
is_favorite = status.isFavorited();
|
||||
text_unescaped = HtmlEscapeHelper.toPlainText(text_html);
|
||||
my_retweet_id = retweeted_by_id == account_id ? id : status.getCurrentUserRetweet();
|
||||
is_possibly_sensitive = status.isPossiblySensitive();
|
||||
mentions = ParcelableUserMention.fromUserMentionEntities(status.getUserMentionEntities());
|
||||
card = ParcelableCardEntity.fromCardEntity(status.getCard(), account_id);
|
||||
place_full_name = getPlaceFullName(status.getPlace());
|
||||
card_name = card != null ? card.name : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@NonNull final ParcelableStatus another) {
|
||||
final long diff = another.id - id;
|
||||
if (diff > Integer.MAX_VALUE) return Integer.MAX_VALUE;
|
||||
if (diff < Integer.MIN_VALUE) return Integer.MIN_VALUE;
|
||||
return (int) diff;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (obj == null) return false;
|
||||
if (!(obj instanceof ParcelableStatus)) return false;
|
||||
final ParcelableStatus other = (ParcelableStatus) obj;
|
||||
return account_id == other.account_id && id == other.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (int) (account_id ^ account_id >>> 32);
|
||||
result = prime * result + (int) (id ^ id >>> 32);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ParcelableStatus{" +
|
||||
|
@ -378,90 +529,6 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
|||
'}';
|
||||
}
|
||||
|
||||
public ParcelableStatus(final Status orig, final long account_id, final boolean is_gap) {
|
||||
this.is_gap = is_gap;
|
||||
this.account_id = account_id;
|
||||
id = orig.getId();
|
||||
timestamp = getTime(orig.getCreatedAt());
|
||||
is_retweet = orig.isRetweet();
|
||||
final Status retweeted = orig.getRetweetedStatus();
|
||||
final User retweet_user = retweeted != null ? orig.getUser() : null;
|
||||
retweet_id = retweeted != null ? retweeted.getId() : -1;
|
||||
retweet_timestamp = retweeted != null ? getTime(retweeted.getCreatedAt()) : -1;
|
||||
retweeted_by_id = retweet_user != null ? retweet_user.getId() : -1;
|
||||
retweeted_by_name = retweet_user != null ? retweet_user.getName() : null;
|
||||
retweeted_by_screen_name = retweet_user != null ? retweet_user.getScreenName() : null;
|
||||
retweeted_by_profile_image = retweet_user != null ?
|
||||
ParseUtils.parseString(retweet_user.getProfileImageUrlHttps()) : null;
|
||||
final Status status = retweeted != null ? retweeted : orig;
|
||||
final User user = status.getUser();
|
||||
user_id = user.getId();
|
||||
user_name = user.getName();
|
||||
user_screen_name = user.getScreenName();
|
||||
user_profile_image_url = ParseUtils.parseString(user.getProfileImageUrlHttps());
|
||||
user_is_protected = user.isProtected();
|
||||
user_is_verified = user.isVerified();
|
||||
user_is_following = user.isFollowing();
|
||||
text_html = TwitterContentUtils.formatStatusText(status);
|
||||
media = ParcelableMedia.fromEntities(status);
|
||||
text_plain = status.getText();
|
||||
retweet_count = status.getRetweetCount();
|
||||
favorite_count = status.getFavoriteCount();
|
||||
reply_count = status.getReplyCount();
|
||||
descendent_reply_count = status.getDescendentReplyCount();
|
||||
in_reply_to_name = TwitterContentUtils.getInReplyToName(status);
|
||||
in_reply_to_screen_name = status.getInReplyToScreenName();
|
||||
in_reply_to_status_id = status.getInReplyToStatusId();
|
||||
in_reply_to_user_id = status.getInReplyToUserId();
|
||||
source = status.getSource();
|
||||
location = ParcelableLocation.fromGeoLocation(status.getGeoLocation());
|
||||
is_favorite = status.isFavorited();
|
||||
text_unescaped = HtmlEscapeHelper.toPlainText(text_html);
|
||||
my_retweet_id = retweeted_by_id == account_id ? id : status.getCurrentUserRetweet();
|
||||
is_possibly_sensitive = status.isPossiblySensitive();
|
||||
mentions = ParcelableUserMention.fromUserMentionEntities(status.getUserMentionEntities());
|
||||
card = ParcelableCardEntity.fromCardEntity(status.getCard(), account_id);
|
||||
place_full_name = getPlaceFullName(status.getPlace());
|
||||
card_name = card != null ? card.name : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getPlaceFullName(@Nullable Place place) {
|
||||
if (place == null) return null;
|
||||
return place.getFullName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@NonNull final ParcelableStatus another) {
|
||||
final long diff = another.id - id;
|
||||
if (diff > Integer.MAX_VALUE) return Integer.MAX_VALUE;
|
||||
if (diff < Integer.MIN_VALUE) return Integer.MIN_VALUE;
|
||||
return (int) diff;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (obj == null) return false;
|
||||
if (!(obj instanceof ParcelableStatus)) return false;
|
||||
final ParcelableStatus other = (ParcelableStatus) obj;
|
||||
return account_id == other.account_id && id == other.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (int) (account_id ^ account_id >>> 32);
|
||||
result = prime * result + (int) (id ^ id >>> 32);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(final JSONParcel out) {
|
||||
out.writeLong("status_id", id);
|
||||
|
@ -502,6 +569,22 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
|||
out.writeParcelableArray("mentions", mentions);
|
||||
out.writeParcelable("card", card);
|
||||
out.writeString("place_full_name", place_full_name);
|
||||
out.writeBoolean("is_quote", is_quote);
|
||||
out.writeLong("quote_id", quote_id);
|
||||
out.writeString("quote_text_html", quote_text_html);
|
||||
out.writeString("quote_text_plain", quote_text_plain);
|
||||
out.writeString("quote_text_unescaped", quote_text_unescaped);
|
||||
out.writeLong("quote_timestamp", quote_timestamp);
|
||||
out.writeLong("quoted_by_user_id", quoted_by_user_id);
|
||||
out.writeString("quoted_by_user_name", quoted_by_user_name);
|
||||
out.writeString("quoted_by_user_screen_name", quoted_by_user_screen_name);
|
||||
out.writeString("quoted_by_user_profile_image", quoted_by_user_profile_image);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getPlaceFullName(@Nullable Place place) {
|
||||
if (place == null) return null;
|
||||
return place.getFullName();
|
||||
}
|
||||
|
||||
private static long getTime(final Date date) {
|
||||
|
@ -516,8 +599,63 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
|||
in_reply_to_user_name, in_reply_to_user_screen_name, my_retweet_id, retweeted_by_user_name,
|
||||
retweeted_by_user_screen_name, retweeted_by_user_profile_image, retweet_id, retweet_timestamp,
|
||||
retweeted_by_user_id, user_id, source, retweet_count, favorite_count, reply_count,
|
||||
descendent_reply_count, is_possibly_sensitive, is_following, media, mentions,
|
||||
card_name, card, place_full_name;
|
||||
descendent_reply_count, is_possibly_sensitive, is_following, media, mentions, card_name,
|
||||
card, place_full_name, is_quote, quote_id, quote_text_html, quote_text_plain, quote_text_unescaped,
|
||||
quote_timestamp, quoted_by_user_id, quoted_by_user_name, quoted_by_user_screen_name,
|
||||
quoted_by_user_profile_image;
|
||||
|
||||
public CursorIndices(final Cursor cursor) {
|
||||
_id = cursor.getColumnIndex(Statuses._ID);
|
||||
account_id = cursor.getColumnIndex(Statuses.ACCOUNT_ID);
|
||||
status_id = cursor.getColumnIndex(Statuses.STATUS_ID);
|
||||
status_timestamp = cursor.getColumnIndex(Statuses.STATUS_TIMESTAMP);
|
||||
user_name = cursor.getColumnIndex(Statuses.USER_NAME);
|
||||
user_screen_name = cursor.getColumnIndex(Statuses.USER_SCREEN_NAME);
|
||||
text_html = cursor.getColumnIndex(Statuses.TEXT_HTML);
|
||||
text_plain = cursor.getColumnIndex(Statuses.TEXT_PLAIN);
|
||||
text_unescaped = cursor.getColumnIndex(Statuses.TEXT_UNESCAPED);
|
||||
user_profile_image_url = cursor.getColumnIndex(Statuses.USER_PROFILE_IMAGE_URL);
|
||||
is_favorite = cursor.getColumnIndex(Statuses.IS_FAVORITE);
|
||||
is_retweet = cursor.getColumnIndex(Statuses.IS_RETWEET);
|
||||
is_quote = cursor.getColumnIndex(Statuses.IS_QUOTE);
|
||||
is_gap = cursor.getColumnIndex(Statuses.IS_GAP);
|
||||
location = cursor.getColumnIndex(Statuses.LOCATION);
|
||||
is_protected = cursor.getColumnIndex(Statuses.IS_PROTECTED);
|
||||
is_verified = cursor.getColumnIndex(Statuses.IS_VERIFIED);
|
||||
in_reply_to_status_id = cursor.getColumnIndex(Statuses.IN_REPLY_TO_STATUS_ID);
|
||||
in_reply_to_user_id = cursor.getColumnIndex(Statuses.IN_REPLY_TO_USER_ID);
|
||||
in_reply_to_user_name = cursor.getColumnIndex(Statuses.IN_REPLY_TO_USER_NAME);
|
||||
in_reply_to_user_screen_name = cursor.getColumnIndex(Statuses.IN_REPLY_TO_USER_SCREEN_NAME);
|
||||
my_retweet_id = cursor.getColumnIndex(Statuses.MY_RETWEET_ID);
|
||||
retweet_id = cursor.getColumnIndex(Statuses.RETWEET_ID);
|
||||
retweet_timestamp = cursor.getColumnIndex(Statuses.RETWEET_TIMESTAMP);
|
||||
retweeted_by_user_id = cursor.getColumnIndex(Statuses.RETWEETED_BY_USER_ID);
|
||||
retweeted_by_user_name = cursor.getColumnIndex(Statuses.RETWEETED_BY_USER_NAME);
|
||||
retweeted_by_user_screen_name = cursor.getColumnIndex(Statuses.RETWEETED_BY_USER_SCREEN_NAME);
|
||||
retweeted_by_user_profile_image = cursor.getColumnIndex(Statuses.RETWEETED_BY_USER_PROFILE_IMAGE);
|
||||
quote_id = cursor.getColumnIndex(Statuses.QUOTE_ID);
|
||||
quote_text_html = cursor.getColumnIndex(Statuses.QUOTE_TEXT_HTML);
|
||||
quote_text_plain = cursor.getColumnIndex(Statuses.QUOTE_TEXT_PLAIN);
|
||||
quote_text_unescaped = cursor.getColumnIndex(Statuses.QUOTE_TEXT_UNESCAPED);
|
||||
quote_timestamp = cursor.getColumnIndex(Statuses.QUOTE_TIMESTAMP);
|
||||
quoted_by_user_id = cursor.getColumnIndex(Statuses.QUOTED_BY_USER_ID);
|
||||
quoted_by_user_name = cursor.getColumnIndex(Statuses.QUOTED_BY_USER_NAME);
|
||||
quoted_by_user_screen_name = cursor.getColumnIndex(Statuses.QUOTED_BY_USER_SCREEN_NAME);
|
||||
quoted_by_user_profile_image = cursor.getColumnIndex(Statuses.QUOTED_BY_USER_PROFILE_IMAGE);
|
||||
user_id = cursor.getColumnIndex(Statuses.USER_ID);
|
||||
source = cursor.getColumnIndex(Statuses.SOURCE);
|
||||
retweet_count = cursor.getColumnIndex(Statuses.RETWEET_COUNT);
|
||||
favorite_count = cursor.getColumnIndex(Statuses.FAVORITE_COUNT);
|
||||
reply_count = cursor.getColumnIndex(Statuses.REPLY_COUNT);
|
||||
descendent_reply_count = cursor.getColumnIndex(Statuses.DESCENDENT_REPLY_COUNT);
|
||||
is_possibly_sensitive = cursor.getColumnIndex(Statuses.IS_POSSIBLY_SENSITIVE);
|
||||
is_following = cursor.getColumnIndex(Statuses.IS_FOLLOWING);
|
||||
media = cursor.getColumnIndex(Statuses.MEDIA_LIST);
|
||||
mentions = cursor.getColumnIndex(Statuses.MENTIONS_LIST);
|
||||
card = cursor.getColumnIndex(Statuses.CARD);
|
||||
card_name = cursor.getColumnIndex(Statuses.CARD_NAME);
|
||||
place_full_name = cursor.getColumnIndex(Statuses.PLACE_FULL_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
@ -565,93 +703,9 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
|||
'}';
|
||||
}
|
||||
|
||||
public CursorIndices(final Cursor cursor) {
|
||||
_id = cursor.getColumnIndex(Statuses._ID);
|
||||
account_id = cursor.getColumnIndex(Statuses.ACCOUNT_ID);
|
||||
status_id = cursor.getColumnIndex(Statuses.STATUS_ID);
|
||||
status_timestamp = cursor.getColumnIndex(Statuses.STATUS_TIMESTAMP);
|
||||
user_name = cursor.getColumnIndex(Statuses.USER_NAME);
|
||||
user_screen_name = cursor.getColumnIndex(Statuses.USER_SCREEN_NAME);
|
||||
text_html = cursor.getColumnIndex(Statuses.TEXT_HTML);
|
||||
text_plain = cursor.getColumnIndex(Statuses.TEXT_PLAIN);
|
||||
text_unescaped = cursor.getColumnIndex(Statuses.TEXT_UNESCAPED);
|
||||
user_profile_image_url = cursor.getColumnIndex(Statuses.USER_PROFILE_IMAGE_URL);
|
||||
is_favorite = cursor.getColumnIndex(Statuses.IS_FAVORITE);
|
||||
is_retweet = cursor.getColumnIndex(Statuses.IS_RETWEET);
|
||||
is_gap = cursor.getColumnIndex(Statuses.IS_GAP);
|
||||
location = cursor.getColumnIndex(Statuses.LOCATION);
|
||||
is_protected = cursor.getColumnIndex(Statuses.IS_PROTECTED);
|
||||
is_verified = cursor.getColumnIndex(Statuses.IS_VERIFIED);
|
||||
in_reply_to_status_id = cursor.getColumnIndex(Statuses.IN_REPLY_TO_STATUS_ID);
|
||||
in_reply_to_user_id = cursor.getColumnIndex(Statuses.IN_REPLY_TO_USER_ID);
|
||||
in_reply_to_user_name = cursor.getColumnIndex(Statuses.IN_REPLY_TO_USER_NAME);
|
||||
in_reply_to_user_screen_name = cursor.getColumnIndex(Statuses.IN_REPLY_TO_USER_SCREEN_NAME);
|
||||
my_retweet_id = cursor.getColumnIndex(Statuses.MY_RETWEET_ID);
|
||||
retweet_id = cursor.getColumnIndex(Statuses.RETWEET_ID);
|
||||
retweet_timestamp = cursor.getColumnIndex(Statuses.RETWEET_TIMESTAMP);
|
||||
retweeted_by_user_id = cursor.getColumnIndex(Statuses.RETWEETED_BY_USER_ID);
|
||||
retweeted_by_user_name = cursor.getColumnIndex(Statuses.RETWEETED_BY_USER_NAME);
|
||||
retweeted_by_user_screen_name = cursor.getColumnIndex(Statuses.RETWEETED_BY_USER_SCREEN_NAME);
|
||||
retweeted_by_user_profile_image = cursor.getColumnIndex(Statuses.RETWEETED_BY_USER_PROFILE_IMAGE);
|
||||
user_id = cursor.getColumnIndex(Statuses.USER_ID);
|
||||
source = cursor.getColumnIndex(Statuses.SOURCE);
|
||||
retweet_count = cursor.getColumnIndex(Statuses.RETWEET_COUNT);
|
||||
favorite_count = cursor.getColumnIndex(Statuses.FAVORITE_COUNT);
|
||||
reply_count = cursor.getColumnIndex(Statuses.REPLY_COUNT);
|
||||
descendent_reply_count = cursor.getColumnIndex(Statuses.DESCENDENT_REPLY_COUNT);
|
||||
is_possibly_sensitive = cursor.getColumnIndex(Statuses.IS_POSSIBLY_SENSITIVE);
|
||||
is_following = cursor.getColumnIndex(Statuses.IS_FOLLOWING);
|
||||
media = cursor.getColumnIndex(Statuses.MEDIA_LIST);
|
||||
mentions = cursor.getColumnIndex(Statuses.MENTIONS_LIST);
|
||||
card = cursor.getColumnIndex(Statuses.CARD);
|
||||
card_name = cursor.getColumnIndex(Statuses.CARD_NAME);
|
||||
place_full_name = cursor.getColumnIndex(Statuses.PLACE_FULL_NAME);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(final Parcel out, final int flags) {
|
||||
out.writeLong(id);
|
||||
out.writeLong(account_id);
|
||||
out.writeLong(timestamp);
|
||||
out.writeLong(user_id);
|
||||
out.writeLong(retweet_id);
|
||||
out.writeLong(retweet_timestamp);
|
||||
out.writeLong(retweeted_by_id);
|
||||
out.writeLong(retweet_count);
|
||||
out.writeLong(favorite_count);
|
||||
out.writeLong(reply_count);
|
||||
out.writeLong(descendent_reply_count);
|
||||
out.writeLong(in_reply_to_status_id);
|
||||
out.writeInt(is_gap ? 1 : 0);
|
||||
out.writeInt(is_retweet ? 1 : 0);
|
||||
out.writeInt(is_favorite ? 1 : 0);
|
||||
out.writeInt(user_is_protected ? 1 : 0);
|
||||
out.writeInt(user_is_verified ? 1 : 0);
|
||||
out.writeString(retweeted_by_name);
|
||||
out.writeString(retweeted_by_screen_name);
|
||||
out.writeString(retweeted_by_profile_image);
|
||||
out.writeString(text_html);
|
||||
out.writeString(text_plain);
|
||||
out.writeString(user_name);
|
||||
out.writeString(user_screen_name);
|
||||
out.writeString(in_reply_to_screen_name);
|
||||
out.writeString(source);
|
||||
out.writeString(user_profile_image_url);
|
||||
out.writeTypedArray(media, flags);
|
||||
out.writeParcelable(location, flags);
|
||||
out.writeLong(my_retweet_id);
|
||||
out.writeInt(is_possibly_sensitive ? 1 : 0);
|
||||
out.writeInt(user_is_following ? 1 : 0);
|
||||
out.writeString(text_unescaped);
|
||||
out.writeLong(in_reply_to_user_id);
|
||||
out.writeString(in_reply_to_name);
|
||||
out.writeTypedArray(mentions, flags);
|
||||
out.writeParcelable(card, flags);
|
||||
out.writeString(place_full_name);
|
||||
}
|
||||
|
||||
public static final class ParcelableCardEntity implements TwidereParcelable {
|
||||
|
||||
public static final Parcelable.Creator<ParcelableCardEntity> CREATOR = new Parcelable.Creator<ParcelableCardEntity>() {
|
||||
|
@ -687,15 +741,6 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
|||
users = src.createTypedArray(ParcelableUser.CREATOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ParcelableCardEntity{" +
|
||||
"name='" + name + '\'' +
|
||||
", users=" + Arrays.toString(users) +
|
||||
", values=" + Arrays.toString(values) +
|
||||
'}';
|
||||
}
|
||||
|
||||
public ParcelableCardEntity(JSONParcel src) {
|
||||
name = src.readString("name");
|
||||
values = src.readParcelableArray("values", ParcelableValueItem.JSON_CREATOR);
|
||||
|
@ -716,6 +761,15 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ParcelableCardEntity{" +
|
||||
"name='" + name + '\'' +
|
||||
", users=" + Arrays.toString(users) +
|
||||
", values=" + Arrays.toString(values) +
|
||||
'}';
|
||||
}
|
||||
|
||||
public static ParcelableCardEntity fromCardEntity(CardEntity card, long account_id) {
|
||||
if (card == null) return null;
|
||||
return new ParcelableCardEntity(card, account_id);
|
||||
|
@ -803,11 +857,6 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final class ParcelableUserValue implements TwidereParcelable {
|
||||
|
||||
public static final Parcelable.Creator<ParcelableUserValue> CREATOR = new Parcelable.Creator<ParcelableUserValue>() {
|
||||
|
@ -969,6 +1018,13 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(name);
|
||||
|
@ -985,4 +1041,56 @@ public class ParcelableStatus implements TwidereParcelable, Comparable<Parcelabl
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(final Parcel out, final int flags) {
|
||||
out.writeLong(id);
|
||||
out.writeLong(account_id);
|
||||
out.writeLong(timestamp);
|
||||
out.writeLong(user_id);
|
||||
out.writeLong(retweet_id);
|
||||
out.writeLong(retweet_timestamp);
|
||||
out.writeLong(retweeted_by_id);
|
||||
out.writeLong(retweet_count);
|
||||
out.writeLong(favorite_count);
|
||||
out.writeLong(reply_count);
|
||||
out.writeLong(descendent_reply_count);
|
||||
out.writeLong(in_reply_to_status_id);
|
||||
out.writeByte((byte) (is_gap ? 1 : 0));
|
||||
out.writeByte((byte) (is_retweet ? 1 : 0));
|
||||
out.writeByte((byte) (is_favorite ? 1 : 0));
|
||||
out.writeByte((byte) (user_is_protected ? 1 : 0));
|
||||
out.writeByte((byte) (user_is_verified ? 1 : 0));
|
||||
out.writeString(retweeted_by_name);
|
||||
out.writeString(retweeted_by_screen_name);
|
||||
out.writeString(retweeted_by_profile_image);
|
||||
out.writeString(text_html);
|
||||
out.writeString(text_plain);
|
||||
out.writeString(user_name);
|
||||
out.writeString(user_screen_name);
|
||||
out.writeString(in_reply_to_screen_name);
|
||||
out.writeString(source);
|
||||
out.writeString(user_profile_image_url);
|
||||
out.writeTypedArray(media, flags);
|
||||
out.writeParcelable(location, flags);
|
||||
out.writeLong(my_retweet_id);
|
||||
out.writeByte((byte) (is_possibly_sensitive ? 1 : 0));
|
||||
out.writeByte((byte) (user_is_following ? 1 : 0));
|
||||
out.writeString(text_unescaped);
|
||||
out.writeLong(in_reply_to_user_id);
|
||||
out.writeString(in_reply_to_name);
|
||||
out.writeTypedArray(mentions, flags);
|
||||
out.writeParcelable(card, flags);
|
||||
out.writeString(place_full_name);
|
||||
out.writeByte((byte) (is_quote ? 1 : 0));
|
||||
out.writeLong(quote_id);
|
||||
out.writeString(quote_text_html);
|
||||
out.writeString(quote_text_plain);
|
||||
out.writeString(quote_text_unescaped);
|
||||
out.writeLong(quote_timestamp);
|
||||
out.writeLong(quoted_by_user_id);
|
||||
out.writeString(quoted_by_user_name);
|
||||
out.writeString(quoted_by_user_screen_name);
|
||||
out.writeString(quoted_by_user_profile_image);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -307,10 +307,9 @@ public final class ContentValuesCreator implements TwidereConstants {
|
|||
values.put(Statuses.ACCOUNT_ID, accountId);
|
||||
values.put(Statuses.STATUS_ID, orig.getId());
|
||||
values.put(Statuses.STATUS_TIMESTAMP, orig.getCreatedAt().getTime());
|
||||
final boolean isRetweet = orig.isRetweet();
|
||||
final Status status;
|
||||
final Status retweetedStatus = isRetweet ? orig.getRetweetedStatus() : null;
|
||||
if (retweetedStatus != null) {
|
||||
if (orig.isRetweet()) {
|
||||
final Status retweetedStatus = orig.getRetweetedStatus();
|
||||
final User retweetUser = orig.getUser();
|
||||
final long retweetedById = retweetUser.getId();
|
||||
values.put(Statuses.RETWEET_ID, retweetedStatus.getId());
|
||||
|
@ -319,12 +318,34 @@ public final class ContentValuesCreator implements TwidereConstants {
|
|||
values.put(Statuses.RETWEETED_BY_USER_NAME, retweetUser.getName());
|
||||
values.put(Statuses.RETWEETED_BY_USER_SCREEN_NAME, retweetUser.getScreenName());
|
||||
values.put(Statuses.RETWEETED_BY_USER_PROFILE_IMAGE, ParseUtils.parseString(retweetUser.getProfileImageUrlHttps()));
|
||||
values.put(Statuses.IS_RETWEET, true);
|
||||
if (retweetedById == accountId) {
|
||||
values.put(Statuses.MY_RETWEET_ID, orig.getId());
|
||||
} else {
|
||||
values.put(Statuses.MY_RETWEET_ID, orig.getCurrentUserRetweet());
|
||||
}
|
||||
status = retweetedStatus;
|
||||
} else if (orig.isQuote()) {
|
||||
final Status quotedStatus = orig.getQuotedStatus();
|
||||
final User quoteUser = orig.getUser();
|
||||
final long quotedById = quoteUser.getId();
|
||||
values.put(Statuses.QUOTE_ID, quotedStatus.getId());
|
||||
final String textHtml = TwitterContentUtils.formatStatusText(orig);
|
||||
values.put(Statuses.QUOTE_TEXT_HTML, textHtml);
|
||||
values.put(Statuses.QUOTE_TEXT_PLAIN, orig.getText());
|
||||
values.put(Statuses.QUOTE_TEXT_UNESCAPED, toPlainText(textHtml));
|
||||
values.put(Statuses.QUOTE_TIMESTAMP, quotedStatus.getCreatedAt().getTime());
|
||||
values.put(Statuses.QUOTED_BY_USER_ID, quotedById);
|
||||
values.put(Statuses.QUOTED_BY_USER_NAME, quoteUser.getName());
|
||||
values.put(Statuses.QUOTED_BY_USER_SCREEN_NAME, quoteUser.getScreenName());
|
||||
values.put(Statuses.QUOTED_BY_USER_PROFILE_IMAGE, ParseUtils.parseString(quoteUser.getProfileImageUrlHttps()));
|
||||
values.put(Statuses.IS_QUOTE, true);
|
||||
if (quotedById == accountId) {
|
||||
values.put(Statuses.MY_QUOTE_ID, orig.getId());
|
||||
// } else {
|
||||
// values.put(Statuses.MY_QUOTE_ID, orig.getCurrentUserRetweet());
|
||||
}
|
||||
status = quotedStatus;
|
||||
} else {
|
||||
values.put(Statuses.MY_RETWEET_ID, orig.getCurrentUserRetweet());
|
||||
status = orig;
|
||||
|
@ -340,10 +361,10 @@ public final class ContentValuesCreator implements TwidereConstants {
|
|||
values.put(Statuses.IS_VERIFIED, user.isVerified());
|
||||
values.put(Statuses.USER_PROFILE_IMAGE_URL, profileImageUrl);
|
||||
values.put(CachedUsers.IS_FOLLOWING, user.isFollowing());
|
||||
final String text_html = TwitterContentUtils.formatStatusText(status);
|
||||
values.put(Statuses.TEXT_HTML, text_html);
|
||||
final String textHtml = TwitterContentUtils.formatStatusText(status);
|
||||
values.put(Statuses.TEXT_HTML, textHtml);
|
||||
values.put(Statuses.TEXT_PLAIN, status.getText());
|
||||
values.put(Statuses.TEXT_UNESCAPED, toPlainText(text_html));
|
||||
values.put(Statuses.TEXT_UNESCAPED, toPlainText(textHtml));
|
||||
values.put(Statuses.RETWEET_COUNT, status.getRetweetCount());
|
||||
values.put(Statuses.REPLY_COUNT, status.getReplyCount());
|
||||
values.put(Statuses.FAVORITE_COUNT, status.getFavoriteCount());
|
||||
|
@ -362,7 +383,6 @@ public final class ContentValuesCreator implements TwidereConstants {
|
|||
if (place != null) {
|
||||
values.put(Statuses.PLACE_FULL_NAME, place.getFullName());
|
||||
}
|
||||
values.put(Statuses.IS_RETWEET, isRetweet);
|
||||
values.put(Statuses.IS_FAVORITE, status.isFavorited());
|
||||
final ParcelableMedia[] media = ParcelableMedia.fromEntities(status);
|
||||
if (media != null) {
|
||||
|
|
|
@ -114,6 +114,8 @@ public interface Status extends Comparable<Status>, TwitterResponse, ExtendedEnt
|
|||
*/
|
||||
Status getRetweetedStatus();
|
||||
|
||||
Status getQuotedStatus();
|
||||
|
||||
/**
|
||||
* returns the source of the tweet
|
||||
*
|
||||
|
@ -151,6 +153,8 @@ public interface Status extends Comparable<Status>, TwitterResponse, ExtendedEnt
|
|||
*/
|
||||
boolean isRetweet();
|
||||
|
||||
boolean isQuote();
|
||||
|
||||
/**
|
||||
* Returns true if the authenticating user has retweeted this tweet, or
|
||||
* false when the tweet was created before this feature was enabled.
|
||||
|
|
|
@ -95,7 +95,7 @@ public final class HttpClientWrapper {
|
|||
}
|
||||
|
||||
public HttpResponse get(final String url, final String signUrl) throws TwitterException {
|
||||
return get(url, signUrl, null, null);
|
||||
return get(url, signUrl, null, null, null);
|
||||
}
|
||||
|
||||
public HttpResponse get(final String url, final String signUrl, final Authorization authorization)
|
||||
|
@ -105,12 +105,37 @@ public final class HttpClientWrapper {
|
|||
|
||||
public HttpResponse get(final String url, final String signUrl, final HttpParameter[] parameters)
|
||||
throws TwitterException {
|
||||
return get(url, signUrl, parameters, null);
|
||||
return get(url, signUrl, parameters, null, null);
|
||||
}
|
||||
|
||||
public HttpResponse get(final String url, final String signUrl, final HttpParameter[] parameters,
|
||||
final Authorization authorization) throws TwitterException {
|
||||
return request(new HttpRequest(GET, url, signUrl, parameters, authorization, requestHeaders));
|
||||
return get(url, signUrl, parameters, authorization, null);
|
||||
}
|
||||
|
||||
public HttpResponse get(final String url, final String signUrl, final HttpParameter[] parameters,
|
||||
final Map<String, List<String>> requestHeaders) throws TwitterException {
|
||||
return get(url, signUrl, parameters, null, requestHeaders);
|
||||
}
|
||||
|
||||
public HttpResponse get(final String url, final String signUrl, final Map<String, List<String>> requestHeaders)
|
||||
throws TwitterException {
|
||||
return get(url, signUrl, null, null, requestHeaders);
|
||||
}
|
||||
|
||||
public HttpResponse get(final String url, final String signUrl, final Authorization authorization,
|
||||
final Map<String, List<String>> requestHeaders) throws TwitterException {
|
||||
return get(url, signUrl, null, authorization, requestHeaders);
|
||||
}
|
||||
|
||||
public HttpResponse get(final String url, final String signUrl, final HttpParameter[] parameters,
|
||||
final Authorization authorization, final Map<String, List<String>> requestHeaders)
|
||||
throws TwitterException {
|
||||
final Map<String, List<String>> headers = new HashMap<>(this.requestHeaders);
|
||||
if (requestHeaders != null) {
|
||||
headers.putAll(requestHeaders);
|
||||
}
|
||||
return request(new HttpRequest(GET, url, signUrl, parameters, authorization, headers));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -92,6 +92,7 @@ final class StatusJSONImpl extends TwitterResponseImpl implements Status {
|
|||
private long[] contributorsIDs;
|
||||
|
||||
private Status retweetedStatus;
|
||||
private Status quotedStatus;
|
||||
private UserMentionEntity[] userMentionEntities;
|
||||
private URLEntity[] urlEntities;
|
||||
private HashtagEntity[] hashtagEntities;
|
||||
|
@ -252,6 +253,11 @@ final class StatusJSONImpl extends TwitterResponseImpl implements Status {
|
|||
return retweetedStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Status getQuotedStatus() {
|
||||
return quotedStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -318,6 +324,11 @@ final class StatusJSONImpl extends TwitterResponseImpl implements Status {
|
|||
return retweetedStatus != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isQuote() {
|
||||
return quotedStatus != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -395,6 +406,16 @@ final class StatusJSONImpl extends TwitterResponseImpl implements Status {
|
|||
logger.warn("failed to parse retweeted_status:" + json);
|
||||
}
|
||||
}
|
||||
|
||||
if (!json.isNull("quoted_status")) {
|
||||
try {
|
||||
quotedStatus = new StatusJSONImpl(json.getJSONObject("quoted_status"));
|
||||
} catch (final JSONException ignore) {
|
||||
ignore.printStackTrace();
|
||||
logger.warn("failed to parse retweeted_status:" + json);
|
||||
}
|
||||
}
|
||||
|
||||
if (!json.isNull("contributors")) {
|
||||
try {
|
||||
final JSONArray contributorsArray = json.getJSONArray("contributors");
|
||||
|
|
|
@ -55,6 +55,7 @@ repositories {
|
|||
jcenter()
|
||||
mavenCentral()
|
||||
maven { url 'https://repo.commonsware.com.s3.amazonaws.com' }
|
||||
maven { url 'https://github.com/suckgamony/RapidDecoder/raw/master/repository' }
|
||||
maven { url "https://jitpack.io" }
|
||||
}
|
||||
|
||||
|
@ -75,16 +76,18 @@ dependencies {
|
|||
compile 'com.squareup:otto:1.3.6'
|
||||
compile 'dnsjava:dnsjava:2.1.7'
|
||||
compile 'com.commonsware.cwac:merge:1.1.1'
|
||||
compile 'com.diegocarloslima:byakugallery:0.1.0'
|
||||
compile 'com.davemorrissey.labs:subsampling-scale-image-view:3.1.3'
|
||||
compile 'com.rengwuxian.materialedittext:library:2.0.3'
|
||||
compile 'com.pnikosis:materialish-progress:1.5'
|
||||
compile 'com.squareup.okhttp:okhttp:2.3.0'
|
||||
compile 'pl.droidsonroids.gif:android-gif-drawable:1.1.3'
|
||||
// Disabled temporarilly due to attribute clash with subsampling-scale-image-view
|
||||
// compile 'pl.droidsonroids.gif:android-gif-drawable:1.1.3'
|
||||
compile 'com.github.mariotaku:MessageBubbleView:1.0'
|
||||
compile 'com.github.mariotaku:DragSortListView:0.6.1'
|
||||
compile 'com.github.mariotaku:SlidingMenu:1.3'
|
||||
compile 'com.github.uucky:ColorPicker-Android:0.9.1'
|
||||
compile 'com.sprylab.android.texturevideoview:texturevideoview:1.0.0'
|
||||
compile 'com.squareup:pollexor:2.0.2'
|
||||
googleCompile 'com.google.android.gms:play-services-maps:7.0.0'
|
||||
googleCompile 'com.google.maps.android:android-maps-utils:0.3.4'
|
||||
fdroidCompile 'org.osmdroid:osmdroid-android:4.3'
|
||||
|
|
|
@ -33,7 +33,7 @@ import static org.mariotaku.twidere.annotation.Preference.Type.STRING;
|
|||
public interface Constants extends TwidereConstants {
|
||||
|
||||
String DATABASES_NAME = "twidere.sqlite";
|
||||
int DATABASES_VERSION = 93;
|
||||
int DATABASES_VERSION = 94;
|
||||
|
||||
int MENU_GROUP_STATUS_EXTENSION = 10;
|
||||
int MENU_GROUP_COMPOSE_EXTENSION = 11;
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
package org.mariotaku.twidere.activity.support;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask.Status;
|
||||
import android.os.Bundle;
|
||||
|
@ -39,12 +38,9 @@ import android.view.View;
|
|||
import android.view.View.OnClickListener;
|
||||
import android.view.View.OnLayoutChangeListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.webkit.WebView;
|
||||
import android.widget.Toast;
|
||||
import android.widget.VideoView;
|
||||
|
||||
import com.diegocarloslima.byakugallery.lib.TileBitmapDrawable;
|
||||
import com.diegocarloslima.byakugallery.lib.TileBitmapDrawable.OnInitializeListener;
|
||||
import com.davemorrissey.labs.subscaleview.ImageSource;
|
||||
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView;
|
||||
import com.pnikosis.materialishprogress.ProgressWheel;
|
||||
import com.sprylab.android.widget.TextureVideoView;
|
||||
|
||||
|
@ -66,15 +62,9 @@ import org.mariotaku.twidere.util.ThemeUtils;
|
|||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.util.VideoLoader;
|
||||
import org.mariotaku.twidere.util.VideoLoader.VideoLoadingListener;
|
||||
import org.mariotaku.twidere.view.TouchImageView;
|
||||
import org.mariotaku.twidere.view.TouchImageView.ZoomListener;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
import pl.droidsonroids.gif.GifDrawable;
|
||||
|
||||
public final class MediaViewerActivity extends ThemedActionBarActivity implements Constants, OnPageChangeListener {
|
||||
|
||||
|
@ -284,9 +274,9 @@ public final class MediaViewerActivity extends ThemedActionBarActivity implement
|
|||
}
|
||||
|
||||
public static final class ImagePageFragment extends BaseSupportFragment
|
||||
implements DownloadListener, LoaderCallbacks<Result>, OnLayoutChangeListener, OnClickListener, ZoomListener {
|
||||
implements DownloadListener, LoaderCallbacks<Result>, OnLayoutChangeListener, OnClickListener {
|
||||
|
||||
private TouchImageView mImageView;
|
||||
private SubsamplingScaleImageView mImageView;
|
||||
private ProgressWheel mProgressBar;
|
||||
private boolean mLoaderInitialized;
|
||||
private float mContentLength;
|
||||
|
@ -295,7 +285,7 @@ public final class MediaViewerActivity extends ThemedActionBarActivity implement
|
|||
@Override
|
||||
public void onBaseViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onBaseViewCreated(view, savedInstanceState);
|
||||
mImageView = (TouchImageView) view.findViewById(R.id.image_view);
|
||||
mImageView = (SubsamplingScaleImageView) view.findViewById(R.id.image_view);
|
||||
mProgressBar = (ProgressWheel) view.findViewById(R.id.progress);
|
||||
}
|
||||
|
||||
|
@ -326,40 +316,24 @@ public final class MediaViewerActivity extends ThemedActionBarActivity implement
|
|||
mImageView.setVisibility(View.VISIBLE);
|
||||
mImageView.setTag(data.file);
|
||||
if (data.useDecoder) {
|
||||
TileBitmapDrawable.attachTileBitmapDrawable(mImageView, data.file.getAbsolutePath(),
|
||||
null, new OnInitializeListener() {
|
||||
@Override
|
||||
public void onStartInitialization() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEndInitialization() {
|
||||
mImageView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateScaleLimit();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
mImageView.setImage(ImageSource.uri(Uri.fromFile(data.file)));
|
||||
} else if ("image/gif".equals(data.options.outMimeType)) {
|
||||
try {
|
||||
final FileDescriptor fd = new RandomAccessFile(data.file, "r").getFD();
|
||||
mImageView.setImageDrawable(new GifDrawable(fd));
|
||||
} catch (IOException e) {
|
||||
mImageView.setImageDrawable(null);
|
||||
mImageView.setTag(null);
|
||||
mImageView.setVisibility(View.GONE);
|
||||
Utils.showErrorMessage(getActivity(), null, e, true);
|
||||
}
|
||||
// try {
|
||||
// final FileDescriptor fd = new RandomAccessFile(data.file, "r").getFD();
|
||||
// mImageView.setImageDrawable(new GifDrawable(fd));
|
||||
// } catch (IOException e) {
|
||||
// mImageView.setImage(null);
|
||||
// mImageView.setTag(null);
|
||||
// mImageView.setVisibility(View.GONE);
|
||||
// Utils.showErrorMessage(getActivity(), null, e, true);
|
||||
// }
|
||||
updateScaleLimit();
|
||||
} else {
|
||||
mImageView.setImageBitmap(data.bitmap);
|
||||
mImageView.setImage(ImageSource.bitmap(data.bitmap));
|
||||
updateScaleLimit();
|
||||
}
|
||||
} else {
|
||||
mImageView.setImageDrawable(null);
|
||||
mImageView.setImage(null);
|
||||
mImageView.setTag(null);
|
||||
mImageView.setVisibility(View.GONE);
|
||||
Utils.showErrorMessage(getActivity(), null, data.exception, true);
|
||||
|
@ -371,10 +345,10 @@ public final class MediaViewerActivity extends ThemedActionBarActivity implement
|
|||
|
||||
@Override
|
||||
public void onLoaderReset(final Loader<TileImageLoader.Result> loader) {
|
||||
final Drawable drawable = mImageView.getDrawable();
|
||||
if (drawable instanceof GifDrawable) {
|
||||
((GifDrawable) drawable).recycle();
|
||||
}
|
||||
// final Drawable drawable = mImageView.getDrawable();
|
||||
// if (drawable instanceof GifDrawable) {
|
||||
// ((GifDrawable) drawable).recycle();
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -462,7 +436,6 @@ public final class MediaViewerActivity extends ThemedActionBarActivity implement
|
|||
super.onActivityCreated(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
mImageView.setOnClickListener(this);
|
||||
mImageView.setZoomListener(this);
|
||||
loadImage();
|
||||
}
|
||||
|
||||
|
@ -510,13 +483,11 @@ public final class MediaViewerActivity extends ThemedActionBarActivity implement
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onZoomOut() {
|
||||
final MediaViewerActivity activity = (MediaViewerActivity) getActivity();
|
||||
activity.setBarVisibility(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onZoomIn() {
|
||||
final MediaViewerActivity activity = (MediaViewerActivity) getActivity();
|
||||
activity.setBarVisibility(false);
|
||||
|
@ -533,16 +504,16 @@ public final class MediaViewerActivity extends ThemedActionBarActivity implement
|
|||
}
|
||||
|
||||
private void updateScaleLimit() {
|
||||
final int viewWidth = mImageView.getWidth(), viewHeight = mImageView.getHeight();
|
||||
final Drawable drawable = mImageView.getDrawable();
|
||||
if (drawable == null || viewWidth <= 0 || viewHeight <= 0) return;
|
||||
final int drawableWidth = drawable.getIntrinsicWidth();
|
||||
final int drawableHeight = drawable.getIntrinsicHeight();
|
||||
if (drawableWidth <= 0 || drawableHeight <= 0) return;
|
||||
final float widthRatio = viewWidth / (float) drawableWidth;
|
||||
final float heightRatio = viewHeight / (float) drawableHeight;
|
||||
mImageView.setMaxScale(Math.max(1, Math.max(heightRatio, widthRatio)));
|
||||
mImageView.resetScale();
|
||||
// final int viewWidth = mImageView.getWidth(), viewHeight = mImageView.getHeight();
|
||||
// final Drawable drawable = mImageView.getDrawable();
|
||||
// if (drawable == null || viewWidth <= 0 || viewHeight <= 0) return;
|
||||
// final int drawableWidth = drawable.getIntrinsicWidth();
|
||||
// final int drawableHeight = drawable.getIntrinsicHeight();
|
||||
// if (drawableWidth <= 0 || drawableHeight <= 0) return;
|
||||
// final float widthRatio = viewWidth / (float) drawableWidth;
|
||||
// final float heightRatio = viewHeight / (float) drawableHeight;
|
||||
// mImageView.setMaxScale(Math.max(1, Math.max(heightRatio, widthRatio)));
|
||||
// mImageView.resetScale();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,9 +38,9 @@ import org.mariotaku.twidere.view.holder.StatusViewHolder;
|
|||
*/
|
||||
public abstract class AbsStatusesAdapter<D> extends Adapter<ViewHolder> implements Constants,
|
||||
IStatusesAdapter<D> {
|
||||
public static final int ITEM_VIEW_TYPE_STATUS = 0;
|
||||
public static final int ITEM_VIEW_TYPE_LOAD_INDICATOR = 0;
|
||||
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_STATUS = 2;
|
||||
|
||||
private final Context mContext;
|
||||
private final LayoutInflater mInflater;
|
||||
|
|
|
@ -114,7 +114,7 @@ public class TwidereApplication extends MultiDexApplication implements Constants
|
|||
|
||||
public ImageDownloader getFullImageDownloader() {
|
||||
if (mFullImageDownloader != null) return mFullImageDownloader;
|
||||
return mFullImageDownloader = new TwidereImageDownloader(this, true);
|
||||
return mFullImageDownloader = new TwidereImageDownloader(this, true, true);
|
||||
}
|
||||
|
||||
public Handler getHandler() {
|
||||
|
@ -133,7 +133,7 @@ public class TwidereApplication extends MultiDexApplication implements Constants
|
|||
|
||||
public ImageDownloader getImageDownloader() {
|
||||
if (mImageDownloader != null) return mImageDownloader;
|
||||
return mImageDownloader = new TwidereImageDownloader(this, false);
|
||||
return mImageDownloader = new TwidereImageDownloader(this, false, true);
|
||||
}
|
||||
|
||||
public ImageLoader getImageLoader() {
|
||||
|
@ -274,7 +274,8 @@ public class TwidereApplication extends MultiDexApplication implements Constants
|
|||
startUsageStatisticsServiceIfNeeded(this);
|
||||
//end
|
||||
} else if (KEY_CONSUMER_KEY.equals(key) || KEY_CONSUMER_SECRET.equals(key) || KEY_API_URL_FORMAT.equals(key)
|
||||
|| KEY_AUTH_TYPE.equals(key) || KEY_SAME_OAUTH_SIGNING_URL.equals(key)) {
|
||||
|| KEY_AUTH_TYPE.equals(key) || KEY_SAME_OAUTH_SIGNING_URL.equals(key) || KEY_THUMBOR_ENABLED.equals(key)
|
||||
|| KEY_THUMBOR_ADDRESS.equals(key) || KEY_THUMBOR_SECURITY_KEY.equals(key)) {
|
||||
final SharedPreferences.Editor editor = preferences.edit();
|
||||
editor.putLong(KEY_API_LAST_CHANGE, System.currentTimeMillis());
|
||||
editor.apply();
|
||||
|
|
|
@ -68,7 +68,6 @@ import android.view.View.OnClickListener;
|
|||
import android.view.ViewGroup;
|
||||
import android.webkit.URLUtil;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Space;
|
||||
import android.widget.TextView;
|
||||
|
||||
|
@ -106,6 +105,7 @@ import org.mariotaku.twidere.util.TwitterCardUtils;
|
|||
import org.mariotaku.twidere.util.UserColorNameUtils;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.util.Utils.OnMediaClickListener;
|
||||
import org.mariotaku.twidere.view.CardMediaContainer;
|
||||
import org.mariotaku.twidere.view.ShapedImageView;
|
||||
import org.mariotaku.twidere.view.StatusTextView;
|
||||
import org.mariotaku.twidere.view.TwitterCardContainer;
|
||||
|
@ -525,7 +525,7 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
|
|||
private final View retweetedByContainer;
|
||||
private final View mediaPreviewContainer;
|
||||
private final View mediaPreviewLoad;
|
||||
private final LinearLayout mediaPreviewGrid;
|
||||
private final CardMediaContainer mediaPreview;
|
||||
|
||||
private final TextView locationView;
|
||||
private final TwitterCardContainer twitterCard;
|
||||
|
@ -549,9 +549,9 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
|
|||
repliesCountView = (TextView) itemView.findViewById(R.id.replies_count);
|
||||
retweetsCountView = (TextView) itemView.findViewById(R.id.retweets_count);
|
||||
favoritesCountView = (TextView) itemView.findViewById(R.id.favorites_count);
|
||||
mediaPreviewContainer = itemView.findViewById(R.id.media_preview);
|
||||
mediaPreviewContainer = itemView.findViewById(R.id.media_preview_container);
|
||||
mediaPreviewLoad = itemView.findViewById(R.id.media_preview_load);
|
||||
mediaPreviewGrid = (LinearLayout) itemView.findViewById(R.id.media_preview_grid);
|
||||
mediaPreview = (CardMediaContainer) itemView.findViewById(R.id.media_preview);
|
||||
locationView = (TextView) itemView.findViewById(R.id.location_view);
|
||||
profileContainer = itemView.findViewById(R.id.profile_container);
|
||||
twitterCard = (TwitterCardContainer) itemView.findViewById(R.id.twitter_card);
|
||||
|
@ -640,16 +640,13 @@ public class StatusFragment extends BaseSupportFragment implements LoaderCallbac
|
|||
} else if (adapter.isDetailMediaExpanded()) {
|
||||
mediaPreviewContainer.setVisibility(View.VISIBLE);
|
||||
mediaPreviewLoad.setVisibility(View.GONE);
|
||||
mediaPreviewGrid.setVisibility(View.VISIBLE);
|
||||
mediaPreviewGrid.removeAllViews();
|
||||
final int maxColumns = resources.getInteger(R.integer.grid_column_image_preview);
|
||||
Utils.addToLinearLayout(mediaPreviewGrid, loader, status.media, status.account_id,
|
||||
maxColumns, adapter.getFragment());
|
||||
mediaPreview.setVisibility(View.VISIBLE);
|
||||
mediaPreview.displayMedia(status.media, loader, status.account_id,
|
||||
adapter.getFragment(), adapter.getImageLoadingHandler());
|
||||
} else {
|
||||
mediaPreviewContainer.setVisibility(View.VISIBLE);
|
||||
mediaPreviewLoad.setVisibility(View.VISIBLE);
|
||||
mediaPreviewGrid.setVisibility(View.GONE);
|
||||
mediaPreviewGrid.removeAllViews();
|
||||
mediaPreview.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (TwitterCardUtils.isCardSupported(status.card)) {
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.preference;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.os.Bundle;
|
||||
import android.preference.SwitchPreference;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Switch;
|
||||
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.fragment.SettingsDetailsFragment;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/4/7.
|
||||
*/
|
||||
public class SwitchSettingsDetailsPreference extends SwitchPreference implements Constants {
|
||||
|
||||
public SwitchSettingsDetailsPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
final TypedArray a = context.obtainStyledAttributes(attrs, new int[]{android.R.attr.src});
|
||||
setFragment(SettingsDetailsFragment.class.getName());
|
||||
final Bundle extras = getExtras();
|
||||
extras.putInt(EXTRA_RESID, a.getResourceId(0, 0));
|
||||
a.recycle();
|
||||
|
||||
}
|
||||
|
||||
public SwitchSettingsDetailsPreference(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, android.R.attr.switchPreferenceStyle);
|
||||
}
|
||||
|
||||
public SwitchSettingsDetailsPreference(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBindView(@NonNull View view) {
|
||||
super.onBindView(view);
|
||||
if (view instanceof ViewGroup) {
|
||||
((ViewGroup) view).setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
|
||||
}
|
||||
final Switch switchView = (Switch) findViewByType(view, Switch.class);
|
||||
if (switchView != null) {
|
||||
switchView.setClickable(true);
|
||||
switchView.setFocusable(true);
|
||||
}
|
||||
}
|
||||
|
||||
private static View findViewByType(View view, Class<? extends View> cls) {
|
||||
if (cls.isAssignableFrom(view.getClass())) return view;
|
||||
if (view instanceof ViewGroup) {
|
||||
for (int i = 0, j = ((ViewGroup) view).getChildCount(); i < j; i++) {
|
||||
final View found = findViewByType(((ViewGroup) view).getChildAt(i), cls);
|
||||
if (found != null) return found;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onClick() {
|
||||
|
||||
}
|
||||
}
|
|
@ -407,7 +407,6 @@ public class BackgroundOperationService extends IntentService implements Constan
|
|||
final ContentLengthInputStream is = new ContentLengthInputStream(file);
|
||||
is.setReadListener(new MessageMediaUploadListener(this, mNotificationManager, builder, text));
|
||||
final MediaUploadResponse uploadResp = twitter.uploadMedia(file.getName(), is, o.outMimeType);
|
||||
// final MediaUploadResponse uploadResp = twitter.uploadMediaBase64(is);
|
||||
directMessage = new ParcelableDirectMessage(twitter.sendDirectMessage(recipientId, text,
|
||||
uploadResp.getId()), accountId, true);
|
||||
if (!file.delete()) {
|
||||
|
|
|
@ -20,7 +20,10 @@
|
|||
package org.mariotaku.twidere.util;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.v4.content.res.ResourcesCompat;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
|
@ -30,6 +33,8 @@ import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
|
|||
import com.nostra13.universalimageloader.core.listener.ImageLoadingProgressListener;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.model.ParcelableMedia;
|
||||
import org.mariotaku.twidere.view.ForegroundImageView;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -55,6 +60,9 @@ public class ImageLoadingHandler implements ImageLoadingListener, ImageLoadingPr
|
|||
public void onLoadingCancelled(final String imageUri, final View view) {
|
||||
if (view == null || imageUri == null || imageUri.equals(mLoadingUris.get(view))) return;
|
||||
mLoadingUris.remove(view);
|
||||
if (view instanceof ForegroundImageView) {
|
||||
((ForegroundImageView) view).setForeground(null);
|
||||
}
|
||||
final ProgressBar progress = findProgressBar(view.getParent());
|
||||
if (progress != null) {
|
||||
progress.setVisibility(View.GONE);
|
||||
|
@ -65,18 +73,38 @@ public class ImageLoadingHandler implements ImageLoadingListener, ImageLoadingPr
|
|||
public void onLoadingComplete(final String imageUri, final View view, final Bitmap bitmap) {
|
||||
if (view == null) return;
|
||||
mLoadingUris.remove(view);
|
||||
final ProgressBar progress = findProgressBar(view.getParent());
|
||||
final ViewGroup parent = (ViewGroup) view.getParent();
|
||||
if (view instanceof ForegroundImageView) {
|
||||
final Drawable foreground;
|
||||
if (isVideoItem(parent)) {
|
||||
foreground = ResourcesCompat.getDrawable(view.getResources(), R.drawable.ic_card_media_play, null);
|
||||
} else {
|
||||
foreground = null;
|
||||
}
|
||||
((ForegroundImageView) view).setForeground(foreground);
|
||||
}
|
||||
final ProgressBar progress = findProgressBar(parent);
|
||||
if (progress != null) {
|
||||
progress.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isVideoItem(ViewGroup parent) {
|
||||
final Object tag = parent.getTag();
|
||||
if (tag instanceof ParcelableMedia) {
|
||||
return ((ParcelableMedia) tag).type == ParcelableMedia.TYPE_VIDEO;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadingFailed(final String imageUri, final View view, final FailReason reason) {
|
||||
if (view == null) return;
|
||||
if (view instanceof ImageView) {
|
||||
if (view instanceof ForegroundImageView) {
|
||||
((ImageView) view).setImageDrawable(null);
|
||||
view.setBackgroundResource(R.drawable.image_preview_refresh);
|
||||
final Drawable foreground = ResourcesCompat.getDrawable(view.getResources(),
|
||||
R.drawable.image_preview_refresh, null);
|
||||
((ForegroundImageView) view).setForeground(foreground);
|
||||
}
|
||||
mLoadingUris.remove(view);
|
||||
final ProgressBar progress = findProgressBar(view.getParent());
|
||||
|
@ -88,8 +116,8 @@ public class ImageLoadingHandler implements ImageLoadingListener, ImageLoadingPr
|
|||
@Override
|
||||
public void onLoadingStarted(final String imageUri, final View view) {
|
||||
if (view == null || imageUri == null || imageUri.equals(mLoadingUris.get(view))) return;
|
||||
if (view instanceof ImageView) {
|
||||
view.setBackgroundResource(0);
|
||||
if (view instanceof ForegroundImageView) {
|
||||
((ForegroundImageView) view).setForeground(null);
|
||||
}
|
||||
mLoadingUris.put(view, imageUri);
|
||||
final ProgressBar progress = findProgressBar(view.getParent());
|
||||
|
|
|
@ -73,7 +73,7 @@ public class OAuthPasswordAuthenticator implements Constants {
|
|||
final String oauthToken = requestToken.getToken();
|
||||
final String authorizationUrl = requestToken.getAuthorizationURL();
|
||||
final HashMap<String, String> inputMap = new HashMap<>();
|
||||
final HttpResponse authorizePage = client.get(authorizationUrl, authorizationUrl, null, null);
|
||||
final HttpResponse authorizePage = client.get(authorizationUrl, authorizationUrl, null, null, null);
|
||||
final List<String> cookieHeaders = authorizePage.getResponseHeaders("Set-Cookie");
|
||||
readInputFromHtml(authorizePage.asReader(),
|
||||
inputMap, INPUT_AUTHENTICITY_TOKEN, INPUT_REDIRECT_AFTER_LOGIN);
|
||||
|
|
|
@ -95,7 +95,6 @@ import android.util.TypedValue;
|
|||
import android.view.Gravity;
|
||||
import android.view.KeyCharacterMap;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
|
@ -106,8 +105,6 @@ import android.view.accessibility.AccessibilityEvent;
|
|||
import android.view.accessibility.AccessibilityManager;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import android.widget.AbsListView;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListAdapter;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
@ -233,8 +230,8 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Locale;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Matcher;
|
||||
|
@ -486,52 +483,6 @@ public final class Utils implements Constants, TwitterConstants {
|
|||
}
|
||||
}
|
||||
|
||||
public static void addToLinearLayout(final LinearLayout container, final MediaLoaderWrapper loader,
|
||||
final List<ParcelableMedia> mediaList, final long accountId,
|
||||
final int maxColumnCount, final OnMediaClickListener mediaClickListener) {
|
||||
if (container.getOrientation() != LinearLayout.VERTICAL)
|
||||
throw new IllegalArgumentException();
|
||||
final Context context = container.getContext();
|
||||
final ImageLoadingHandler loadingHandler = new ImageLoadingHandler(R.id.media_preview_progress);
|
||||
final LayoutInflater inflater = LayoutInflater.from(context);
|
||||
final ListIterator<ParcelableMedia> iterator = mediaList.listIterator();
|
||||
final int imageCount = mediaList.size();
|
||||
final double imageCountSqrt = Math.sqrt(imageCount);
|
||||
final int bestColumnCount = imageCountSqrt % 1 == 0 ? (int) imageCountSqrt : maxColumnCount;
|
||||
final int firstColumn = imageCount % bestColumnCount, fullRowCount = imageCount / bestColumnCount;
|
||||
final int rowCount = fullRowCount + (firstColumn > 0 ? 1 : 0);
|
||||
final View.OnClickListener clickListener = new ImageGridClickListener(mediaClickListener, accountId);
|
||||
container.setMotionEventSplittingEnabled(false);
|
||||
for (int currentRow = 0; currentRow < rowCount; currentRow++) {
|
||||
final LinearLayout rowContainer = new LinearLayout(context);
|
||||
rowContainer.setOrientation(LinearLayout.HORIZONTAL);
|
||||
rowContainer.setMotionEventSplittingEnabled(false);
|
||||
container.addView(rowContainer, LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT);
|
||||
final int columnCount = currentRow == 0 && firstColumn > 0 ? firstColumn : bestColumnCount;
|
||||
for (int currentColumn = 0; currentColumn < columnCount; currentColumn++) {
|
||||
final ParcelableMedia media = iterator.next();
|
||||
final View item = inflater.inflate(R.layout.grid_item_media_preview, rowContainer, false);
|
||||
item.setTag(media);
|
||||
if (mediaClickListener != null) {
|
||||
item.setOnClickListener(clickListener);
|
||||
}
|
||||
final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) item.getLayoutParams();
|
||||
lp.weight = 1.0f;
|
||||
rowContainer.addView(item, lp);
|
||||
final ImageView imageView = (ImageView) item.findViewById(R.id.media_preview_item);
|
||||
loader.displayPreviewImage(imageView, media.page_url, loadingHandler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void addToLinearLayout(final LinearLayout container, final MediaLoaderWrapper loader,
|
||||
final ParcelableMedia[] mediaArray, final long accountId,
|
||||
final int maxColumnCount, final OnMediaClickListener listener) {
|
||||
addToLinearLayout(container, loader, Arrays.asList(mediaArray), accountId, maxColumnCount,
|
||||
listener);
|
||||
}
|
||||
|
||||
public static void announceForAccessibilityCompat(final Context context, final View view, final CharSequence text,
|
||||
final Class<?> cls) {
|
||||
final AccessibilityManager accessibilityManager = (AccessibilityManager) context
|
||||
|
@ -2194,13 +2145,15 @@ public final class Utils implements Constants, TwitterConstants {
|
|||
}
|
||||
|
||||
public static HttpResponse getRedirectedHttpResponse(final HttpClientWrapper client, final String url,
|
||||
final String signUrl, final Authorization auth) throws TwitterException {
|
||||
final String signUrl, final Authorization auth,
|
||||
final HashMap<String, List<String>> additionalHeaders)
|
||||
throws TwitterException {
|
||||
if (url == null) return null;
|
||||
final ArrayList<String> urls = new ArrayList<>();
|
||||
urls.add(url);
|
||||
HttpResponse resp;
|
||||
try {
|
||||
resp = client.get(url, signUrl, auth);
|
||||
resp = client.get(url, signUrl, auth, additionalHeaders);
|
||||
} catch (final TwitterException te) {
|
||||
if (isRedirected(te.getStatusCode())) {
|
||||
resp = te.getHttpResponse();
|
||||
|
@ -2213,7 +2166,7 @@ public final class Utils implements Constants, TwitterConstants {
|
|||
if (urls.contains(request_url)) throw new TwitterException("Too many redirects");
|
||||
urls.add(request_url);
|
||||
try {
|
||||
resp = client.get(request_url, request_url);
|
||||
resp = client.get(request_url, request_url, additionalHeaders);
|
||||
} catch (final TwitterException te) {
|
||||
if (isRedirected(te.getStatusCode())) {
|
||||
resp = te.getHttpResponse();
|
||||
|
|
|
@ -30,6 +30,7 @@ import com.squareup.otto.Bus;
|
|||
import org.mariotaku.twidere.app.TwidereApplication;
|
||||
import org.mariotaku.twidere.model.SingleResponse;
|
||||
import org.mariotaku.twidere.task.ManagedAsyncTask;
|
||||
import org.mariotaku.twidere.util.imageloader.TwidereImageDownloader;
|
||||
import org.mariotaku.twidere.util.message.VideoLoadFinishedEvent;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -52,7 +53,7 @@ public class VideoLoader {
|
|||
final TwidereApplication app = TwidereApplication.getInstance(context);
|
||||
mContext = context;
|
||||
mDiskCache = app.getDiskCache();
|
||||
mImageDownloader = app.getImageDownloader();
|
||||
mImageDownloader = new TwidereImageDownloader(context, false, false);
|
||||
mTaskManager = app.getAsyncTaskManager();
|
||||
mBus = app.getMessageBus();
|
||||
}
|
||||
|
|
|
@ -21,17 +21,23 @@ package org.mariotaku.twidere.util.imageloader;
|
|||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.text.TextUtils;
|
||||
import android.webkit.URLUtil;
|
||||
|
||||
import com.nostra13.universalimageloader.core.assist.ContentLengthInputStream;
|
||||
import com.nostra13.universalimageloader.core.download.BaseImageDownloader;
|
||||
import com.squareup.pollexor.Thumbor;
|
||||
import com.squareup.pollexor.ThumborUrlBuilder;
|
||||
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.constant.SharedPreferenceConstants;
|
||||
import org.mariotaku.twidere.model.ParcelableAccount;
|
||||
import org.mariotaku.twidere.model.ParcelableAccount.ParcelableCredentials;
|
||||
import org.mariotaku.twidere.model.ParcelableMedia;
|
||||
import org.mariotaku.twidere.util.MediaPreviewUtils;
|
||||
import org.mariotaku.twidere.util.SharedPreferencesWrapper;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -40,6 +46,7 @@ import java.util.Locale;
|
|||
|
||||
import twitter4j.TwitterException;
|
||||
import twitter4j.auth.Authorization;
|
||||
import twitter4j.http.HeaderMap;
|
||||
import twitter4j.http.HttpClientWrapper;
|
||||
import twitter4j.http.HttpResponse;
|
||||
|
||||
|
@ -52,106 +59,134 @@ import static org.mariotaku.twidere.util.Utils.getTwitterProfileImageOfSize;
|
|||
|
||||
public class TwidereImageDownloader extends BaseImageDownloader implements Constants {
|
||||
|
||||
private final Context mContext;
|
||||
private HttpClientWrapper mClient;
|
||||
private boolean mFastImageLoading;
|
||||
private final boolean mFullImage;
|
||||
private final String mTwitterProfileImageSize;
|
||||
private final Context mContext;
|
||||
private final SharedPreferencesWrapper mPreferences;
|
||||
private final boolean mUseThumbor;
|
||||
private Thumbor mThumbor;
|
||||
private HttpClientWrapper mClient;
|
||||
private boolean mFastImageLoading;
|
||||
private final boolean mFullImage;
|
||||
private final String mTwitterProfileImageSize;
|
||||
|
||||
public TwidereImageDownloader(final Context context, final boolean fullImage) {
|
||||
super(context);
|
||||
mContext = context;
|
||||
mFullImage = fullImage;
|
||||
mTwitterProfileImageSize = context.getString(R.string.profile_image_size);
|
||||
reloadConnectivitySettings();
|
||||
}
|
||||
public TwidereImageDownloader(final Context context, final boolean fullImage, final boolean useThumbor) {
|
||||
super(context);
|
||||
mContext = context;
|
||||
mPreferences = SharedPreferencesWrapper.getInstance(context, SHARED_PREFERENCES_NAME,
|
||||
Context.MODE_PRIVATE, SharedPreferenceConstants.class);
|
||||
mFullImage = fullImage;
|
||||
mTwitterProfileImageSize = context.getString(R.string.profile_image_size);
|
||||
mUseThumbor = useThumbor;
|
||||
reloadConnectivitySettings();
|
||||
|
||||
public void reloadConnectivitySettings() {
|
||||
mClient = getImageLoaderHttpClient(mContext);
|
||||
mFastImageLoading = mContext.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE).getBoolean(
|
||||
KEY_FAST_IMAGE_LOADING, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InputStream getStreamFromNetwork(final String uriString, final Object extras) throws IOException {
|
||||
if (uriString == null) return null;
|
||||
final ParcelableMedia media = MediaPreviewUtils.getAllAvailableImage(uriString, mFullImage, mFullImage
|
||||
|| !mFastImageLoading ? mClient : null);
|
||||
try {
|
||||
final String mediaUrl = media != null ? media.media_url : uriString;
|
||||
if (isTwitterProfileImage(uriString)) {
|
||||
final String replaced = getTwitterProfileImageOfSize(mediaUrl, mTwitterProfileImageSize);
|
||||
return getStreamFromNetworkInternal(replaced, extras);
|
||||
} else
|
||||
return getStreamFromNetworkInternal(mediaUrl, extras);
|
||||
} catch (final TwitterException e) {
|
||||
final int statusCode = e.getStatusCode();
|
||||
if (statusCode != -1 && isTwitterProfileImage(uriString) && !uriString.contains("_normal.")) {
|
||||
try {
|
||||
return getStreamFromNetworkInternal(getNormalTwitterProfileImage(uriString), extras);
|
||||
} catch (final TwitterException e2) {
|
||||
public void reloadConnectivitySettings() {
|
||||
mClient = getImageLoaderHttpClient(mContext);
|
||||
mFastImageLoading = mPreferences.getBoolean(KEY_FAST_IMAGE_LOADING);
|
||||
if (mUseThumbor && mPreferences.getBoolean(KEY_THUMBOR_ENABLED)) {
|
||||
final String address = mPreferences.getString(KEY_THUMBOR_ADDRESS, null);
|
||||
final String securityKey = mPreferences.getString(KEY_THUMBOR_SECURITY_KEY, null);
|
||||
if (URLUtil.isValidUrl(address)) {
|
||||
if (TextUtils.isEmpty(securityKey)) {
|
||||
mThumbor = Thumbor.create(address);
|
||||
} else {
|
||||
mThumbor = Thumbor.create(address, securityKey);
|
||||
}
|
||||
} else {
|
||||
mThumbor = null;
|
||||
}
|
||||
} else {
|
||||
mThumbor = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
throw new IOException(String.format(Locale.US, "Error downloading image %s, error code: %d", uriString,
|
||||
statusCode));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected InputStream getStreamFromNetwork(final String uriString, final Object extras) throws IOException {
|
||||
if (uriString == null) return null;
|
||||
final ParcelableMedia media = MediaPreviewUtils.getAllAvailableImage(uriString, mFullImage, mFullImage
|
||||
|| !mFastImageLoading ? mClient : null);
|
||||
try {
|
||||
final String mediaUrl = media != null ? media.media_url : uriString;
|
||||
if (isTwitterProfileImage(uriString)) {
|
||||
final String replaced = getTwitterProfileImageOfSize(mediaUrl, mTwitterProfileImageSize);
|
||||
return getStreamFromNetworkInternal(replaced, extras);
|
||||
} else
|
||||
return getStreamFromNetworkInternal(mediaUrl, extras);
|
||||
} catch (final TwitterException e) {
|
||||
final int statusCode = e.getStatusCode();
|
||||
if (statusCode != -1 && isTwitterProfileImage(uriString) && !uriString.contains("_normal.")) {
|
||||
try {
|
||||
return getStreamFromNetworkInternal(getNormalTwitterProfileImage(uriString), extras);
|
||||
} catch (final TwitterException e2) {
|
||||
|
||||
private String getReplacedUri(final Uri uri, final String apiUrlFormat) {
|
||||
if (uri == null) return null;
|
||||
if (apiUrlFormat == null) return uri.toString();
|
||||
if (isTwitterUri(uri)) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
final String domain = uri.getHost().replaceAll("\\.?twitter.com", "");
|
||||
final String path = uri.getPath();
|
||||
sb.append(Utils.getApiUrl(apiUrlFormat, domain, path));
|
||||
final String query = uri.getQuery();
|
||||
if (!TextUtils.isEmpty(query)) {
|
||||
sb.append("?");
|
||||
sb.append(query);
|
||||
}
|
||||
final String fragment = uri.getFragment();
|
||||
if (!TextUtils.isEmpty(fragment)) {
|
||||
sb.append("#");
|
||||
sb.append(fragment);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
return uri.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new IOException(String.format(Locale.US, "Error downloading image %s, error code: %d", uriString,
|
||||
statusCode));
|
||||
}
|
||||
}
|
||||
|
||||
private ContentLengthInputStream getStreamFromNetworkInternal(final String uriString, final Object extras)
|
||||
throws IOException, TwitterException {
|
||||
final Uri uri = Uri.parse(uriString);
|
||||
final Authorization auth;
|
||||
final ParcelableCredentials account;
|
||||
if (isTwitterAuthRequired(uri) && extras instanceof AccountExtra) {
|
||||
final AccountExtra accountExtra = (AccountExtra) extras;
|
||||
account = ParcelableAccount.getCredentials(mContext, accountExtra.account_id);
|
||||
auth = getTwitterAuthorization(mContext, accountExtra.account_id);
|
||||
} else {
|
||||
account = null;
|
||||
auth = null;
|
||||
}
|
||||
final String modifiedUri = getReplacedUri(uri, account != null ? account.api_url_format : null);
|
||||
final HttpResponse resp = getRedirectedHttpResponse(mClient, modifiedUri, uriString, auth);
|
||||
return new ContentLengthInputStream(resp.asStream(), (int) resp.getContentLength());
|
||||
}
|
||||
private String getReplacedUri(final Uri uri, final String apiUrlFormat) {
|
||||
if (uri == null) return null;
|
||||
if (apiUrlFormat == null) return uri.toString();
|
||||
if (isTwitterUri(uri)) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
final String domain = uri.getHost().replaceAll("\\.?twitter.com", "");
|
||||
final String path = uri.getPath();
|
||||
sb.append(Utils.getApiUrl(apiUrlFormat, domain, path));
|
||||
final String query = uri.getQuery();
|
||||
if (!TextUtils.isEmpty(query)) {
|
||||
sb.append("?");
|
||||
sb.append(query);
|
||||
}
|
||||
final String fragment = uri.getFragment();
|
||||
if (!TextUtils.isEmpty(fragment)) {
|
||||
sb.append("#");
|
||||
sb.append(fragment);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
return uri.toString();
|
||||
}
|
||||
|
||||
private boolean isTwitterAuthRequired(final Uri uri) {
|
||||
if (uri == null) return false;
|
||||
return "ton.twitter.com".equalsIgnoreCase(uri.getHost());
|
||||
}
|
||||
private ContentLengthInputStream getStreamFromNetworkInternal(final String uriString, final Object extras)
|
||||
throws IOException, TwitterException {
|
||||
final Uri uri = Uri.parse(uriString);
|
||||
final Authorization auth;
|
||||
final ParcelableCredentials account;
|
||||
if (isTwitterAuthRequired(uri) && extras instanceof AccountExtra) {
|
||||
final AccountExtra accountExtra = (AccountExtra) extras;
|
||||
account = ParcelableAccount.getCredentials(mContext, accountExtra.account_id);
|
||||
auth = getTwitterAuthorization(mContext, accountExtra.account_id);
|
||||
} else {
|
||||
account = null;
|
||||
auth = null;
|
||||
}
|
||||
String modifiedUri = getReplacedUri(uri, account != null ? account.api_url_format : null);
|
||||
if (mThumbor != null) {
|
||||
modifiedUri = mThumbor.buildImage(modifiedUri).filter(ThumborUrlBuilder.quality(85)).toUrl();
|
||||
}
|
||||
final HeaderMap additionalHeaders = new HeaderMap();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
additionalHeaders.addHeader("Accept", "image/webp, */*");
|
||||
}
|
||||
final HttpResponse resp = getRedirectedHttpResponse(mClient, modifiedUri, uriString, auth, additionalHeaders);
|
||||
return new ContentLengthInputStream(resp.asStream(), (int) resp.getContentLength());
|
||||
}
|
||||
|
||||
private boolean isTwitterProfileImage(final String uriString) {
|
||||
if (TextUtils.isEmpty(uriString)) return false;
|
||||
return PATTERN_TWITTER_PROFILE_IMAGES.matcher(uriString).matches();
|
||||
}
|
||||
private boolean isTwitterAuthRequired(final Uri uri) {
|
||||
if (uri == null) return false;
|
||||
return "ton.twitter.com".equalsIgnoreCase(uri.getHost());
|
||||
}
|
||||
|
||||
private boolean isTwitterUri(final Uri uri) {
|
||||
if (uri == null) return false;
|
||||
return "ton.twitter.com".equalsIgnoreCase(uri.getHost());
|
||||
}
|
||||
private boolean isTwitterProfileImage(final String uriString) {
|
||||
if (TextUtils.isEmpty(uriString)) return false;
|
||||
return PATTERN_TWITTER_PROFILE_IMAGES.matcher(uriString).matches();
|
||||
}
|
||||
|
||||
private boolean isTwitterUri(final Uri uri) {
|
||||
if (uri == null) return false;
|
||||
return "ton.twitter.com".equalsIgnoreCase(uri.getHost());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,22 +25,18 @@ import android.util.AttributeSet;
|
|||
import android.view.View;
|
||||
|
||||
public class MediaViewPager extends ViewPager {
|
||||
|
||||
|
||||
public MediaViewPager(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public MediaViewPager(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
|
||||
if (v instanceof TouchImageView) {
|
||||
return v.canScrollHorizontally(dx);
|
||||
} else {
|
||||
return super.canScroll(v, checkV, dx, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
public MediaViewPager(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public MediaViewPager(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
|
||||
return super.canScroll(v, checkV, dx, x, y);
|
||||
}
|
||||
}
|
|
@ -1,533 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.view;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ScaleGestureDetector;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.view.animation.Transformation;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.diegocarloslima.byakugallery.lib.FlingScroller;
|
||||
import com.diegocarloslima.byakugallery.lib.TouchGestureDetector;
|
||||
|
||||
public class TouchImageView extends ImageView {
|
||||
|
||||
private static final int DOUBLE_TAP_ANIMATION_DURATION = 300;
|
||||
private static final int SCALE_END_ANIMATION_DURATION = 200;
|
||||
|
||||
private Drawable mDrawable;
|
||||
private int mDrawableIntrinsicWidth;
|
||||
private int mDrawableIntrinsicHeight;
|
||||
|
||||
private final TouchGestureDetector mTouchGestureDetector;
|
||||
|
||||
private final Matrix mMatrix = new Matrix();
|
||||
private final float[] mMatrixValues = new float[9];
|
||||
|
||||
private float mScale;
|
||||
private float mMaxScale = 1;
|
||||
private float mTranslationX;
|
||||
private float mTranslationY;
|
||||
|
||||
private Float mLastFocusX;
|
||||
private Float mLastFocusY;
|
||||
|
||||
private final FlingScroller mFlingScroller = new FlingScroller();
|
||||
private boolean mIsAnimatingBack;
|
||||
private ZoomListener mZoomListener;
|
||||
|
||||
public TouchImageView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public TouchImageView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public TouchImageView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
|
||||
final TouchGestureDetector.OnTouchGestureListener listener = new TouchGestureDetector.OnTouchGestureListener() {
|
||||
|
||||
@Override
|
||||
public boolean onSingleTapConfirmed(MotionEvent e) {
|
||||
return performClick();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongPress(MotionEvent e) {
|
||||
performLongClick();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDoubleTap(MotionEvent e) {
|
||||
loadMatrixValues();
|
||||
|
||||
final float minScale = getMinScale();
|
||||
// If we have already zoomed in, we should return to our initial scale value (minScale). Otherwise, scale to full size
|
||||
final boolean shouldZoomOut = mScale > minScale;
|
||||
final float targetScale = shouldZoomOut ? minScale : mMaxScale;
|
||||
|
||||
// First, we try to keep the focused point in the same position when the animation ends
|
||||
final float desiredTranslationX = e.getX() - (e.getX() - mTranslationX) * (targetScale / mScale);
|
||||
final float desiredTranslationY = e.getY() - (e.getY() - mTranslationY) * (targetScale / mScale);
|
||||
|
||||
// Here, we apply a correction to avoid unwanted blank spaces
|
||||
final float targetTranslationX = desiredTranslationX + computeTranslation(getMeasuredWidth(), mDrawableIntrinsicWidth * targetScale, desiredTranslationX, 0);
|
||||
final float targetTranslationY = desiredTranslationY + computeTranslation(getMeasuredHeight(), mDrawableIntrinsicHeight * targetScale, desiredTranslationY, 0);
|
||||
|
||||
clearAnimation();
|
||||
final Animation animation = new TouchAnimation(targetScale, targetTranslationX, targetTranslationY);
|
||||
animation.setDuration(DOUBLE_TAP_ANIMATION_DURATION);
|
||||
startAnimation(animation);
|
||||
|
||||
if (mZoomListener != null) {
|
||||
if (shouldZoomOut) {
|
||||
mZoomListener.onZoomOut();
|
||||
} else {
|
||||
mZoomListener.onZoomIn();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
|
||||
// Sometimes, this method is called just after an onScaleEnd event. In this case, we want to wait until we animate back our image
|
||||
if (mIsAnimatingBack) {
|
||||
return false;
|
||||
}
|
||||
|
||||
loadMatrixValues();
|
||||
|
||||
final float currentDrawableWidth = mDrawableIntrinsicWidth * mScale;
|
||||
final float currentDrawableHeight = mDrawableIntrinsicHeight * mScale;
|
||||
|
||||
final float dx = computeTranslation(getMeasuredWidth(), currentDrawableWidth, mTranslationX, -distanceX);
|
||||
final float dy = computeTranslation(getMeasuredHeight(), currentDrawableHeight, mTranslationY, -distanceY);
|
||||
mMatrix.postTranslate(dx, dy);
|
||||
|
||||
clearAnimation();
|
||||
ViewCompat.postInvalidateOnAnimation(TouchImageView.this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
||||
// Sometimes, this method is called just after an onScaleEnd event. In this case, we want to wait until we animate back our image
|
||||
if (mIsAnimatingBack) {
|
||||
return false;
|
||||
}
|
||||
|
||||
loadMatrixValues();
|
||||
|
||||
final float horizontalSideFreeSpace = (getMeasuredWidth() - mDrawableIntrinsicWidth * mScale) / 2F;
|
||||
final float minTranslationX = horizontalSideFreeSpace > 0 ? horizontalSideFreeSpace : getMeasuredWidth() - mDrawableIntrinsicWidth * mScale;
|
||||
final float maxTranslationX = horizontalSideFreeSpace > 0 ? horizontalSideFreeSpace : 0;
|
||||
|
||||
final float verticalSideFreeSpace = (getMeasuredHeight() - mDrawableIntrinsicHeight * mScale) / 2F;
|
||||
final float minTranslationY = verticalSideFreeSpace > 0 ? verticalSideFreeSpace : getMeasuredHeight() - mDrawableIntrinsicHeight * mScale;
|
||||
final float maxTranslationY = verticalSideFreeSpace > 0 ? verticalSideFreeSpace : 0;
|
||||
|
||||
// Using FlingScroller here. The results were better than the Scroller class
|
||||
// https://android.googlesource.com/platform/packages/apps/Gallery2/+/master/src/com/android/gallery3d/ui/FlingScroller.java
|
||||
mFlingScroller.fling(Math.round(mTranslationX), Math.round(mTranslationY), Math.round(velocityX), Math.round(velocityY), Math.round(minTranslationX), Math.round(maxTranslationX), Math.round(minTranslationY), Math.round(maxTranslationY));
|
||||
|
||||
clearAnimation();
|
||||
final Animation animation = new FlingAnimation();
|
||||
animation.setDuration(mFlingScroller.getDuration());
|
||||
animation.setInterpolator(new LinearInterpolator());
|
||||
startAnimation(animation);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onScaleBegin(ScaleGestureDetector detector) {
|
||||
mLastFocusX = null;
|
||||
mLastFocusY = null;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onScale(ScaleGestureDetector detector) {
|
||||
loadMatrixValues();
|
||||
|
||||
float currentDrawableWidth = mDrawableIntrinsicWidth * mScale;
|
||||
float currentDrawableHeight = mDrawableIntrinsicHeight * mScale;
|
||||
|
||||
final float focusX = computeFocus(getMeasuredWidth(), currentDrawableWidth, mTranslationX, detector.getFocusX());
|
||||
final float focusY = computeFocus(getMeasuredHeight(), currentDrawableHeight, mTranslationY, detector.getFocusY());
|
||||
|
||||
// Here, we provide the ability to scroll while scaling
|
||||
if (mLastFocusX != null && mLastFocusY != null) {
|
||||
final float dx = computeScaleTranslation(getMeasuredWidth(), currentDrawableWidth, mTranslationX, focusX - mLastFocusX);
|
||||
final float dy = computeScaleTranslation(getMeasuredHeight(), currentDrawableHeight, mTranslationY, focusY - mLastFocusY);
|
||||
|
||||
if (dx != 0 || dy != 0) {
|
||||
mMatrix.postTranslate(dx, dy);
|
||||
}
|
||||
}
|
||||
|
||||
final float scale = computeScale(getMinScale(), mMaxScale, mScale, detector.getScaleFactor());
|
||||
mMatrix.postScale(scale, scale, focusX, focusY);
|
||||
|
||||
mLastFocusX = focusX;
|
||||
mLastFocusY = focusY;
|
||||
|
||||
clearAnimation();
|
||||
ViewCompat.postInvalidateOnAnimation(TouchImageView.this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScaleEnd(ScaleGestureDetector detector) {
|
||||
loadMatrixValues();
|
||||
|
||||
final float currentDrawableWidth = mDrawableIntrinsicWidth * mScale;
|
||||
final float currentDrawableHeight = mDrawableIntrinsicHeight * mScale;
|
||||
|
||||
final float dx = computeTranslation(getMeasuredWidth(), currentDrawableWidth, mTranslationX, 0);
|
||||
final float dy = computeTranslation(getMeasuredHeight(), currentDrawableHeight, mTranslationY, 0);
|
||||
|
||||
if (Math.abs(dx) < 1 && Math.abs(dy) < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
final float targetTranslationX = mTranslationX + dx;
|
||||
final float targetTranslationY = mTranslationY + dy;
|
||||
|
||||
clearAnimation();
|
||||
final Animation animation = new TouchAnimation(mScale, targetTranslationX, targetTranslationY);
|
||||
animation.setDuration(SCALE_END_ANIMATION_DURATION);
|
||||
startAnimation(animation);
|
||||
|
||||
mIsAnimatingBack = true;
|
||||
}
|
||||
};
|
||||
|
||||
mTouchGestureDetector = new TouchGestureDetector(context, listener);
|
||||
|
||||
super.setScaleType(ScaleType.MATRIX);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
final int oldMeasuredWidth = getMeasuredWidth();
|
||||
final int oldMeasuredHeight = getMeasuredHeight();
|
||||
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
|
||||
if (oldMeasuredWidth != getMeasuredWidth() || oldMeasuredHeight != getMeasuredHeight()) {
|
||||
resetToInitialState();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.setImageMatrix(mMatrix);
|
||||
super.onDraw(canvas);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImageMatrix(Matrix matrix) {
|
||||
if (matrix == null) {
|
||||
matrix = new Matrix();
|
||||
}
|
||||
|
||||
if (!mMatrix.equals(matrix)) {
|
||||
mMatrix.set(matrix);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Matrix getImageMatrix() {
|
||||
return mMatrix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
mTouchGestureDetector.onTouchEvent(event);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearAnimation() {
|
||||
super.clearAnimation();
|
||||
mIsAnimatingBack = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImageDrawable(Drawable drawable) {
|
||||
super.setImageDrawable(drawable);
|
||||
if (mDrawable != drawable) {
|
||||
mDrawable = drawable;
|
||||
if (drawable != null) {
|
||||
mDrawableIntrinsicWidth = drawable.getIntrinsicWidth();
|
||||
mDrawableIntrinsicHeight = drawable.getIntrinsicHeight();
|
||||
resetToInitialState();
|
||||
} else {
|
||||
mDrawableIntrinsicWidth = 0;
|
||||
mDrawableIntrinsicHeight = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScaleType(ScaleType scaleType) {
|
||||
if (scaleType != ScaleType.MATRIX) {
|
||||
throw new IllegalArgumentException("Unsupported scaleType. Only ScaleType.MATRIX is allowed.");
|
||||
}
|
||||
super.setScaleType(scaleType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canScrollHorizontally(int direction) {
|
||||
loadMatrixValues();
|
||||
return canScroll(getMeasuredWidth(), mDrawableIntrinsicWidth * mScale, mTranslationX, direction);
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
|
||||
@Override
|
||||
public boolean canScrollVertically(int direction) {
|
||||
loadMatrixValues();
|
||||
return canScroll(getMeasuredHeight(), mDrawableIntrinsicHeight * mScale, mTranslationY, direction);
|
||||
}
|
||||
|
||||
public void setMaxScale(float maxScale) {
|
||||
mMaxScale = maxScale;
|
||||
}
|
||||
|
||||
public void resetScale() {
|
||||
loadMatrixValues();
|
||||
|
||||
// If we have already zoomed in, we should return to our initial scale value (minScale). Otherwise, scale to full size
|
||||
final float targetScale = getMinScale();
|
||||
|
||||
// First, we try to keep the focused point in the same position when the animation ends
|
||||
final float desiredTranslationX = getWidth() / 2;
|
||||
final float desiredTranslationY = getHeight() / 2;
|
||||
|
||||
// Here, we apply a correction to avoid unwanted blank spaces
|
||||
final float targetTranslationX = desiredTranslationX + computeTranslation(getMeasuredWidth(), mDrawableIntrinsicWidth * targetScale, desiredTranslationX, 0);
|
||||
final float targetTranslationY = desiredTranslationY + computeTranslation(getMeasuredHeight(), mDrawableIntrinsicHeight * targetScale, desiredTranslationY, 0);
|
||||
|
||||
clearAnimation();
|
||||
final Animation animation = new TouchAnimation(targetScale, targetTranslationX, targetTranslationY);
|
||||
animation.setDuration(0);
|
||||
startAnimation(animation);
|
||||
|
||||
}
|
||||
|
||||
private void resetToInitialState() {
|
||||
mMatrix.reset();
|
||||
final float minScale = getMinScale();
|
||||
mMatrix.postScale(minScale, minScale);
|
||||
|
||||
final float[] values = new float[9];
|
||||
mMatrix.getValues(values);
|
||||
|
||||
final float freeSpaceHorizontal = (getMeasuredWidth() - (mDrawableIntrinsicWidth * minScale)) / 2F;
|
||||
final float freeSpaceVertical = (getMeasuredHeight() - (mDrawableIntrinsicHeight * minScale)) / 2F;
|
||||
mMatrix.postTranslate(freeSpaceHorizontal, freeSpaceVertical);
|
||||
|
||||
invalidate();
|
||||
}
|
||||
|
||||
private void loadMatrixValues() {
|
||||
mMatrix.getValues(mMatrixValues);
|
||||
mScale = mMatrixValues[Matrix.MSCALE_X];
|
||||
mTranslationX = mMatrixValues[Matrix.MTRANS_X];
|
||||
mTranslationY = mMatrixValues[Matrix.MTRANS_Y];
|
||||
}
|
||||
|
||||
private float getMinScale() {
|
||||
float minScale = Math.min(getMeasuredWidth() / (float) mDrawableIntrinsicWidth, getMeasuredHeight() / (float) mDrawableIntrinsicHeight);
|
||||
if (minScale > mMaxScale) {
|
||||
minScale = mMaxScale;
|
||||
}
|
||||
return minScale;
|
||||
}
|
||||
|
||||
private static boolean canScroll(float viewSize, float drawableSize, float currentTranslation, int direction) {
|
||||
if (direction > 0) {
|
||||
return Math.round(currentTranslation) < 0;
|
||||
} else if (direction < 0) {
|
||||
return Math.round(currentTranslation) > viewSize - Math.round(drawableSize);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// The translation values must be in [0, viewSize - drawableSize], except if we have free space. In that case we will translate to half of the free space
|
||||
private static float computeTranslation(float viewSize, float drawableSize, float currentTranslation, float delta) {
|
||||
final float sideFreeSpace = (viewSize - drawableSize) / 2F;
|
||||
|
||||
if (sideFreeSpace > 0) {
|
||||
return sideFreeSpace - currentTranslation;
|
||||
} else if (currentTranslation + delta > 0) {
|
||||
return -currentTranslation;
|
||||
} else if (currentTranslation + delta < viewSize - drawableSize) {
|
||||
return viewSize - drawableSize - currentTranslation;
|
||||
}
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
private static float computeScaleTranslation(float viewSize, float drawableSize, float currentTranslation, float delta) {
|
||||
final float minTranslation = viewSize > drawableSize ? 0 : viewSize - drawableSize;
|
||||
final float maxTranslation = viewSize > drawableSize ? viewSize - drawableSize : 0;
|
||||
|
||||
if (currentTranslation < minTranslation && delta > 0) {
|
||||
if (currentTranslation + delta > maxTranslation) {
|
||||
return maxTranslation - currentTranslation;
|
||||
} else {
|
||||
return delta;
|
||||
}
|
||||
} else if (currentTranslation > maxTranslation && delta < 0) {
|
||||
if (currentTranslation + delta < minTranslation) {
|
||||
return minTranslation - currentTranslation;
|
||||
} else {
|
||||
return delta;
|
||||
}
|
||||
} else if (currentTranslation > minTranslation && currentTranslation < maxTranslation) {
|
||||
if (currentTranslation + delta < minTranslation) {
|
||||
return minTranslation - currentTranslation;
|
||||
} else if (currentTranslation + delta > maxTranslation) {
|
||||
return maxTranslation - currentTranslation;
|
||||
} else {
|
||||
return delta;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If our focal point is outside the image, we will project it to our image bounds
|
||||
private static float computeFocus(float viewSize, float drawableSize, float currentTranslation, float focusCoordinate) {
|
||||
if (currentTranslation > 0 && focusCoordinate < currentTranslation) {
|
||||
return currentTranslation;
|
||||
} else if (currentTranslation < viewSize - drawableSize && focusCoordinate > currentTranslation + drawableSize) {
|
||||
return drawableSize + currentTranslation;
|
||||
}
|
||||
|
||||
return focusCoordinate;
|
||||
}
|
||||
|
||||
// The scale values must be in [minScale, maxScale]
|
||||
private static float computeScale(float minScale, float maxScale, float currentScale, float delta) {
|
||||
if (currentScale * delta < minScale) {
|
||||
return minScale / currentScale;
|
||||
} else if (currentScale * delta > maxScale) {
|
||||
return maxScale / currentScale;
|
||||
}
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
private class FlingAnimation extends Animation {
|
||||
|
||||
@Override
|
||||
protected void applyTransformation(float interpolatedTime, Transformation t) {
|
||||
mFlingScroller.computeScrollOffset(interpolatedTime);
|
||||
|
||||
loadMatrixValues();
|
||||
|
||||
final float dx = mFlingScroller.getCurrX() - mTranslationX;
|
||||
final float dy = mFlingScroller.getCurrY() - mTranslationY;
|
||||
mMatrix.postTranslate(dx, dy);
|
||||
|
||||
ViewCompat.postInvalidateOnAnimation(TouchImageView.this);
|
||||
}
|
||||
}
|
||||
|
||||
private class TouchAnimation extends Animation {
|
||||
|
||||
private float initialScale;
|
||||
private float initialTranslationX;
|
||||
private float initialTranslationY;
|
||||
|
||||
private float targetScale;
|
||||
private float targetTranslationX;
|
||||
private float targetTranslationY;
|
||||
|
||||
TouchAnimation(float targetScale, float targetTranslationX, float targetTranslationY) {
|
||||
loadMatrixValues();
|
||||
|
||||
this.initialScale = mScale;
|
||||
this.initialTranslationX = mTranslationX;
|
||||
this.initialTranslationY = mTranslationY;
|
||||
|
||||
this.targetScale = targetScale;
|
||||
this.targetTranslationX = targetTranslationX;
|
||||
this.targetTranslationY = targetTranslationY;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyTransformation(float interpolatedTime, Transformation t) {
|
||||
loadMatrixValues();
|
||||
|
||||
if (interpolatedTime >= 1) {
|
||||
mMatrix.getValues(mMatrixValues);
|
||||
mMatrixValues[Matrix.MSCALE_X] = this.targetScale;
|
||||
mMatrixValues[Matrix.MSCALE_Y] = this.targetScale;
|
||||
mMatrixValues[Matrix.MTRANS_X] = this.targetTranslationX;
|
||||
mMatrixValues[Matrix.MTRANS_Y] = this.targetTranslationY;
|
||||
mMatrix.setValues(mMatrixValues);
|
||||
|
||||
} else {
|
||||
final float scaleFactor = (this.initialScale + interpolatedTime * (this.targetScale - this.initialScale)) / mScale;
|
||||
mMatrix.postScale(scaleFactor, scaleFactor);
|
||||
|
||||
mMatrix.getValues(mMatrixValues);
|
||||
final float currentTranslationX = mMatrixValues[Matrix.MTRANS_X];
|
||||
final float currentTranslationY = mMatrixValues[Matrix.MTRANS_Y];
|
||||
|
||||
final float dx = this.initialTranslationX + interpolatedTime * (this.targetTranslationX - this.initialTranslationX) - currentTranslationX;
|
||||
final float dy = this.initialTranslationY + interpolatedTime * (this.targetTranslationY - this.initialTranslationY) - currentTranslationY;
|
||||
mMatrix.postTranslate(dx, dy);
|
||||
}
|
||||
|
||||
ViewCompat.postInvalidateOnAnimation(TouchImageView.this);
|
||||
}
|
||||
}
|
||||
|
||||
public void setZoomListener(ZoomListener listener) {
|
||||
mZoomListener = listener;
|
||||
}
|
||||
|
||||
public static interface ZoomListener {
|
||||
void onZoomOut();
|
||||
|
||||
void onZoomIn();
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@ package org.mariotaku.twidere.view.holder;
|
|||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.PorterDuff.Mode;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.CardView;
|
||||
|
@ -35,6 +34,7 @@ import org.mariotaku.twidere.util.UserColorNameUtils;
|
|||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.util.Utils.OnMediaClickListener;
|
||||
import org.mariotaku.twidere.view.CardMediaContainer;
|
||||
import org.mariotaku.twidere.view.ForegroundColorView;
|
||||
import org.mariotaku.twidere.view.ShapedImageView;
|
||||
import org.mariotaku.twidere.view.ShortTimeView;
|
||||
import org.mariotaku.twidere.view.iface.IColorLabelView;
|
||||
|
@ -62,12 +62,16 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements Constan
|
|||
private final ImageView profileTypeView;
|
||||
private final ImageView extraTypeView;
|
||||
private final TextView textView;
|
||||
private final TextView quoteTextView;
|
||||
private final TextView nameView, screenNameView;
|
||||
private final TextView quotedNameView, quotedScreenNameView;
|
||||
private final TextView replyRetweetView;
|
||||
private final ShortTimeView timeView;
|
||||
private final CardMediaContainer mediaPreviewContainer;
|
||||
private final CardMediaContainer mediaPreview;
|
||||
private final TextView replyCountView, retweetCountView, favoriteCountView;
|
||||
private final View quotedNameContainer;
|
||||
private final IColorLabelView itemContent;
|
||||
private final ForegroundColorView quoteIndicator;
|
||||
|
||||
private StatusClickListener statusClickListener;
|
||||
|
||||
|
@ -79,13 +83,19 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements Constan
|
|||
profileTypeView = (ImageView) itemView.findViewById(R.id.profile_type);
|
||||
extraTypeView = (ImageView) itemView.findViewById(R.id.extra_type);
|
||||
textView = (TextView) itemView.findViewById(R.id.text);
|
||||
quoteTextView = (TextView) itemView.findViewById(R.id.quote_text);
|
||||
nameView = (TextView) itemView.findViewById(R.id.name);
|
||||
screenNameView = (TextView) itemView.findViewById(R.id.screen_name);
|
||||
quotedNameView = (TextView) itemView.findViewById(R.id.quoted_name);
|
||||
quotedScreenNameView = (TextView) itemView.findViewById(R.id.quoted_screen_name);
|
||||
replyRetweetIcon = (ImageView) itemView.findViewById(R.id.reply_retweet_icon);
|
||||
replyRetweetView = (TextView) itemView.findViewById(R.id.reply_retweet_status);
|
||||
timeView = (ShortTimeView) itemView.findViewById(R.id.time);
|
||||
|
||||
mediaPreviewContainer = (CardMediaContainer) itemView.findViewById(R.id.media_preview_container);
|
||||
mediaPreview = (CardMediaContainer) itemView.findViewById(R.id.media_preview);
|
||||
quotedNameContainer = itemView.findViewById(R.id.quoted_name_container);
|
||||
|
||||
quoteIndicator = (ForegroundColorView) itemView.findViewById(R.id.quote_indicator);
|
||||
|
||||
replyCountView = (TextView) itemView.findViewById(R.id.reply_count);
|
||||
retweetCountView = (TextView) itemView.findViewById(R.id.retweet_count);
|
||||
|
@ -100,7 +110,7 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements Constan
|
|||
screenNameView.setText("@" + TWIDERE_PREVIEW_SCREEN_NAME);
|
||||
textView.setText(toPlainText(TWIDERE_PREVIEW_TEXT_HTML));
|
||||
timeView.setTime(System.currentTimeMillis());
|
||||
mediaPreviewContainer.displayMedia(R.drawable.nyan_stars_background);
|
||||
mediaPreview.displayMedia(R.drawable.nyan_stars_background);
|
||||
}
|
||||
|
||||
public void displayStatus(final ParcelableStatus status, final boolean displayInReplyTo) {
|
||||
|
@ -109,42 +119,35 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements Constan
|
|||
|
||||
public void displayStatus(@NonNull final ParcelableStatus status, @Nullable final TranslationResult translation,
|
||||
final boolean displayInReplyTo, final boolean shouldDisplayExtraType) {
|
||||
final Context context = adapter.getContext();
|
||||
final MediaLoaderWrapper loader = adapter.getImageLoader();
|
||||
final ImageLoadingHandler handler = adapter.getImageLoadingHandler();
|
||||
final AsyncTwitterWrapper twitter = adapter.getTwitterWrapper();
|
||||
final TwidereLinkify linkify = adapter.getTwidereLinkify();
|
||||
final boolean displayProfileImage = adapter.isProfileImageEnabled();
|
||||
final boolean displayMediaPreview = adapter.isMediaPreviewEnabled();
|
||||
final boolean displayAccountsColor = adapter.shouldShowAccountsColor();
|
||||
final Context context = adapter.getContext();
|
||||
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;
|
||||
|
||||
replyRetweetIcon.setColorFilter(replyRetweetView.getCurrentTextColor(), Mode.SRC_ATOP);
|
||||
final long reply_count = status.reply_count;
|
||||
final long retweet_count;
|
||||
final long favorite_count;
|
||||
|
||||
if (status.retweet_id > 0) {
|
||||
replyRetweetView.setVisibility(View.VISIBLE);
|
||||
replyRetweetIcon.setVisibility(View.VISIBLE);
|
||||
final String retweetedBy = UserColorNameUtils.getDisplayName(context, status.retweeted_by_id,
|
||||
status.retweeted_by_name, status.retweeted_by_screen_name, nameFirst);
|
||||
replyRetweetView.setText(context.getString(R.string.name_retweeted, retweetedBy));
|
||||
replyRetweetIcon.setImageResource(R.drawable.ic_activity_action_retweet);
|
||||
} else if (status.in_reply_to_status_id > 0 && status.in_reply_to_user_id > 0 && displayInReplyTo) {
|
||||
replyRetweetView.setVisibility(View.VISIBLE);
|
||||
replyRetweetIcon.setVisibility(View.VISIBLE);
|
||||
} else if (status.in_reply_to_status_id > 0 && status.in_reply_to_user_id > 0 && displayInReplyTo) {
|
||||
final String inReplyTo = UserColorNameUtils.getDisplayName(context, status.in_reply_to_user_id,
|
||||
status.in_reply_to_name, status.in_reply_to_screen_name, nameFirst);
|
||||
replyRetweetView.setText(context.getString(R.string.in_reply_to_name, inReplyTo));
|
||||
replyRetweetIcon.setImageResource(R.drawable.ic_activity_action_reply);
|
||||
replyRetweetView.setVisibility(View.VISIBLE);
|
||||
replyRetweetIcon.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
replyRetweetView.setVisibility(View.GONE);
|
||||
replyRetweetIcon.setVisibility(View.GONE);
|
||||
replyRetweetView.setText(null);
|
||||
}
|
||||
|
||||
|
||||
final int typeIconRes = getUserTypeIconRes(status.user_is_verified, status.user_is_protected);
|
||||
if (typeIconRes != 0) {
|
||||
profileTypeView.setImageResource(typeIconRes);
|
||||
|
@ -154,64 +157,102 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements Constan
|
|||
profileTypeView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
nameView.setText(status.user_name);
|
||||
screenNameView.setText("@" + status.user_screen_name);
|
||||
timeView.setTime(status.timestamp);
|
||||
if (status.is_quote) {
|
||||
quotedNameView.setText(status.user_name);
|
||||
quotedScreenNameView.setText("@" + status.user_screen_name);
|
||||
timeView.setTime(status.quote_timestamp);
|
||||
nameView.setText(status.quoted_by_user_name);
|
||||
screenNameView.setText("@" + status.quoted_by_user_screen_name);
|
||||
|
||||
final int userColor = UserColorNameUtils.getUserColor(context, status.user_id);
|
||||
itemContent.drawStart(userColor);
|
||||
if (adapter.getLinkHighlightingStyle() == VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
|
||||
quoteTextView.setText(status.quote_text_unescaped);
|
||||
} else {
|
||||
quoteTextView.setText(Html.fromHtml(status.quote_text_html));
|
||||
linkify.applyAllLinks(quoteTextView, status.account_id, getLayoutPosition(),
|
||||
status.is_possibly_sensitive, adapter.getLinkHighlightingStyle());
|
||||
quoteTextView.setMovementMethod(null);
|
||||
}
|
||||
|
||||
if (displayAccountsColor) {
|
||||
quotedNameContainer.setVisibility(View.VISIBLE);
|
||||
quoteTextView.setVisibility(View.VISIBLE);
|
||||
quoteIndicator.setVisibility(View.VISIBLE);
|
||||
|
||||
quoteIndicator.setColor(UserColorNameUtils.getUserColor(context, status.user_id));
|
||||
|
||||
if (adapter.isProfileImageEnabled()) {
|
||||
profileTypeView.setVisibility(View.VISIBLE);
|
||||
profileImageView.setVisibility(View.VISIBLE);
|
||||
loader.displayProfileImage(profileImageView, status.quoted_by_user_profile_image);
|
||||
} else {
|
||||
profileTypeView.setVisibility(View.GONE);
|
||||
profileImageView.setVisibility(View.GONE);
|
||||
loader.cancelDisplayTask(profileImageView);
|
||||
}
|
||||
|
||||
final int userColor = UserColorNameUtils.getUserColor(context, status.quoted_by_user_id);
|
||||
itemContent.drawStart(userColor);
|
||||
} else {
|
||||
nameView.setText(status.user_name);
|
||||
screenNameView.setText("@" + status.user_screen_name);
|
||||
timeView.setTime(status.timestamp);
|
||||
|
||||
quotedNameContainer.setVisibility(View.GONE);
|
||||
quoteTextView.setVisibility(View.GONE);
|
||||
quoteIndicator.setVisibility(View.GONE);
|
||||
|
||||
if (adapter.isProfileImageEnabled()) {
|
||||
final String user_profile_image_url = status.user_profile_image_url;
|
||||
profileTypeView.setVisibility(View.VISIBLE);
|
||||
profileImageView.setVisibility(View.VISIBLE);
|
||||
loader.displayProfileImage(profileImageView, user_profile_image_url);
|
||||
} else {
|
||||
profileTypeView.setVisibility(View.GONE);
|
||||
profileImageView.setVisibility(View.GONE);
|
||||
loader.cancelDisplayTask(profileImageView);
|
||||
}
|
||||
final int userColor = UserColorNameUtils.getUserColor(context, status.user_id);
|
||||
itemContent.drawStart(userColor);
|
||||
}
|
||||
|
||||
|
||||
if (adapter.shouldShowAccountsColor()) {
|
||||
itemContent.drawEnd(Utils.getAccountColor(context, status.account_id));
|
||||
} else {
|
||||
itemContent.drawEnd();
|
||||
}
|
||||
profileImageView.setStyle(profileImageStyle);
|
||||
|
||||
if (displayProfileImage) {
|
||||
profileTypeView.setVisibility(View.VISIBLE);
|
||||
profileImageView.setVisibility(View.VISIBLE);
|
||||
loader.displayProfileImage(profileImageView, status.user_profile_image_url);
|
||||
} else {
|
||||
profileTypeView.setVisibility(View.GONE);
|
||||
profileImageView.setVisibility(View.GONE);
|
||||
loader.cancelDisplayTask(profileImageView);
|
||||
}
|
||||
|
||||
if (displayMediaPreview) {
|
||||
mediaPreviewContainer.setStyle(mediaPreviewStyle);
|
||||
if (media != null && media.length > 0) {
|
||||
mediaPreviewContainer.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mediaPreviewContainer.setVisibility(View.GONE);
|
||||
}
|
||||
mediaPreviewContainer.displayMedia(media, loader, status.account_id, this, handler);
|
||||
if (adapter.isMediaPreviewEnabled()) {
|
||||
mediaPreview.setStyle(adapter.getMediaPreviewStyle());
|
||||
mediaPreview.setVisibility(status.media != null && status.media.length > 0 ? View.VISIBLE : View.GONE);
|
||||
mediaPreview.displayMedia(status.media, loader, status.account_id, this,
|
||||
adapter.getImageLoadingHandler());
|
||||
} else {
|
||||
mediaPreviewContainer.setVisibility(View.GONE);
|
||||
mediaPreview.setVisibility(View.GONE);
|
||||
}
|
||||
if (translation != null) {
|
||||
textView.setText(translation.getText());
|
||||
} else if (linkHighlightingStyle == VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
|
||||
if (adapter.getLinkHighlightingStyle() == VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
|
||||
textView.setText(status.text_unescaped);
|
||||
} else {
|
||||
textView.setText(Html.fromHtml(status.text_html));
|
||||
linkify.applyAllLinks(textView, status.account_id, getLayoutPosition(),
|
||||
status.is_possibly_sensitive, linkHighlightingStyle);
|
||||
status.is_possibly_sensitive,
|
||||
adapter.getLinkHighlightingStyle());
|
||||
textView.setMovementMethod(null);
|
||||
}
|
||||
|
||||
if (status.reply_count > 0) {
|
||||
replyCountView.setText(Utils.getLocalizedNumber(Locale.getDefault(), status.reply_count));
|
||||
if (reply_count > 0) {
|
||||
replyCountView.setText(Utils.getLocalizedNumber(Locale.getDefault(), reply_count));
|
||||
} else {
|
||||
replyCountView.setText(null);
|
||||
}
|
||||
|
||||
final long retweet_count;
|
||||
if (twitter.isDestroyingStatus(status.account_id, status.my_retweet_id)) {
|
||||
retweetCountView.setActivated(false);
|
||||
retweet_count = Math.max(0, status.favorite_count - 1);
|
||||
retweet_count = Math.max(0, status.retweet_count - 1);
|
||||
} else {
|
||||
final boolean creatingRetweet = twitter.isCreatingRetweet(status.account_id, status.id);
|
||||
retweetCountView.setActivated(creatingRetweet || Utils.isMyRetweet(status));
|
||||
retweetCountView.setActivated(creatingRetweet || Utils.isMyRetweet(status.account_id,
|
||||
status.retweeted_by_id, status.my_retweet_id));
|
||||
retweet_count = status.retweet_count + (creatingRetweet ? 1 : 0);
|
||||
}
|
||||
if (retweet_count > 0) {
|
||||
|
@ -219,9 +260,6 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements Constan
|
|||
} else {
|
||||
retweetCountView.setText(null);
|
||||
}
|
||||
retweetCountView.setEnabled(!status.user_is_protected);
|
||||
|
||||
final long favorite_count;
|
||||
if (twitter.isDestroyingFavorite(status.account_id, status.id)) {
|
||||
favoriteCountView.setActivated(false);
|
||||
favorite_count = Math.max(0, status.favorite_count - 1);
|
||||
|
@ -255,7 +293,6 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements Constan
|
|||
final long favorite_count;
|
||||
|
||||
final long account_id = cursor.getLong(indices.account_id);
|
||||
final long timestamp = cursor.getLong(indices.status_timestamp);
|
||||
final long user_id = cursor.getLong(indices.user_id);
|
||||
final long status_id = cursor.getLong(indices.status_id);
|
||||
final long retweet_id = cursor.getLong(indices.retweet_id);
|
||||
|
@ -264,15 +301,8 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements Constan
|
|||
final long in_reply_to_status_id = cursor.getLong(indices.in_reply_to_status_id);
|
||||
final long in_reply_to_user_id = cursor.getLong(indices.in_reply_to_user_id);
|
||||
|
||||
final boolean user_is_protected = cursor.getInt(indices.is_protected) == 1;
|
||||
|
||||
final String user_name = cursor.getString(indices.user_name);
|
||||
final String user_screen_name = cursor.getString(indices.user_screen_name);
|
||||
final String user_profile_image_url = cursor.getString(indices.user_profile_image_url);
|
||||
final String retweeted_by_name = cursor.getString(indices.retweeted_by_user_name);
|
||||
final String retweeted_by_screen_name = cursor.getString(indices.retweeted_by_user_screen_name);
|
||||
final String in_reply_to_name = cursor.getString(indices.in_reply_to_user_name);
|
||||
final String in_reply_to_screen_name = cursor.getString(indices.in_reply_to_user_screen_name);
|
||||
final String card_name = cursor.getString(indices.card_name);
|
||||
final String place_full_name = cursor.getString(indices.place_full_name);
|
||||
|
||||
|
@ -282,6 +312,8 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements Constan
|
|||
cursor.getString(indices.location));
|
||||
|
||||
if (retweet_id > 0) {
|
||||
final String retweeted_by_name = cursor.getString(indices.retweeted_by_user_name);
|
||||
final String retweeted_by_screen_name = cursor.getString(indices.retweeted_by_user_screen_name);
|
||||
final String retweetedBy = UserColorNameUtils.getDisplayName(context, retweeted_by_id,
|
||||
retweeted_by_name, retweeted_by_screen_name, nameFirst);
|
||||
replyRetweetView.setText(context.getString(R.string.name_retweeted, retweetedBy));
|
||||
|
@ -289,6 +321,8 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements Constan
|
|||
replyRetweetView.setVisibility(View.VISIBLE);
|
||||
replyRetweetIcon.setVisibility(View.VISIBLE);
|
||||
} else if (in_reply_to_status_id > 0 && in_reply_to_user_id > 0 && displayInReplyTo) {
|
||||
final String in_reply_to_name = cursor.getString(indices.in_reply_to_user_name);
|
||||
final String in_reply_to_screen_name = cursor.getString(indices.in_reply_to_user_screen_name);
|
||||
final String inReplyTo = UserColorNameUtils.getDisplayName(context, in_reply_to_user_id,
|
||||
in_reply_to_name, in_reply_to_screen_name, nameFirst);
|
||||
replyRetweetView.setText(context.getString(R.string.in_reply_to_name, inReplyTo));
|
||||
|
@ -300,8 +334,8 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements Constan
|
|||
replyRetweetIcon.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
final int typeIconRes = getUserTypeIconRes(cursor.getInt(indices.is_verified) == 1,
|
||||
user_is_protected);
|
||||
final int typeIconRes = getUserTypeIconRes(cursor.getShort(indices.is_verified) == 1,
|
||||
cursor.getShort(indices.is_protected) == 1);
|
||||
if (typeIconRes != 0) {
|
||||
profileTypeView.setImageResource(typeIconRes);
|
||||
profileTypeView.setVisibility(View.VISIBLE);
|
||||
|
@ -310,12 +344,64 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements Constan
|
|||
profileTypeView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
nameView.setText(user_name);
|
||||
screenNameView.setText("@" + user_screen_name);
|
||||
timeView.setTime(timestamp);
|
||||
if (cursor.getShort(indices.is_quote) == 1) {
|
||||
quotedNameView.setText(user_name);
|
||||
quotedScreenNameView.setText("@" + user_screen_name);
|
||||
timeView.setTime(cursor.getLong(indices.quote_timestamp));
|
||||
nameView.setText(cursor.getString(indices.quoted_by_user_name));
|
||||
screenNameView.setText("@" + cursor.getString(indices.quoted_by_user_screen_name));
|
||||
|
||||
if (adapter.getLinkHighlightingStyle() == VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
|
||||
quoteTextView.setText(cursor.getString(indices.quote_text_unescaped));
|
||||
} else {
|
||||
quoteTextView.setText(Html.fromHtml(cursor.getString(indices.quote_text_html)));
|
||||
linkify.applyAllLinks(quoteTextView, account_id, getLayoutPosition(),
|
||||
cursor.getShort(indices.is_possibly_sensitive) == 1,
|
||||
adapter.getLinkHighlightingStyle());
|
||||
quoteTextView.setMovementMethod(null);
|
||||
}
|
||||
|
||||
quotedNameContainer.setVisibility(View.VISIBLE);
|
||||
quoteTextView.setVisibility(View.VISIBLE);
|
||||
quoteIndicator.setVisibility(View.VISIBLE);
|
||||
|
||||
quoteIndicator.setColor(UserColorNameUtils.getUserColor(context, user_id));
|
||||
|
||||
if (adapter.isProfileImageEnabled()) {
|
||||
profileTypeView.setVisibility(View.VISIBLE);
|
||||
profileImageView.setVisibility(View.VISIBLE);
|
||||
loader.displayProfileImage(profileImageView, cursor.getString(indices.quoted_by_user_profile_image));
|
||||
} else {
|
||||
profileTypeView.setVisibility(View.GONE);
|
||||
profileImageView.setVisibility(View.GONE);
|
||||
loader.cancelDisplayTask(profileImageView);
|
||||
}
|
||||
|
||||
final int userColor = UserColorNameUtils.getUserColor(context, cursor.getLong(indices.quoted_by_user_id));
|
||||
itemContent.drawStart(userColor);
|
||||
} else {
|
||||
nameView.setText(user_name);
|
||||
screenNameView.setText("@" + user_screen_name);
|
||||
timeView.setTime(cursor.getLong(indices.status_timestamp));
|
||||
|
||||
quotedNameContainer.setVisibility(View.GONE);
|
||||
quoteTextView.setVisibility(View.GONE);
|
||||
quoteIndicator.setVisibility(View.GONE);
|
||||
|
||||
if (adapter.isProfileImageEnabled()) {
|
||||
final String user_profile_image_url = cursor.getString(indices.user_profile_image_url);
|
||||
profileTypeView.setVisibility(View.VISIBLE);
|
||||
profileImageView.setVisibility(View.VISIBLE);
|
||||
loader.displayProfileImage(profileImageView, user_profile_image_url);
|
||||
} else {
|
||||
profileTypeView.setVisibility(View.GONE);
|
||||
profileImageView.setVisibility(View.GONE);
|
||||
loader.cancelDisplayTask(profileImageView);
|
||||
}
|
||||
final int userColor = UserColorNameUtils.getUserColor(context, user_id);
|
||||
itemContent.drawStart(userColor);
|
||||
}
|
||||
|
||||
final int userColor = UserColorNameUtils.getUserColor(context, user_id);
|
||||
itemContent.drawStart(userColor);
|
||||
|
||||
if (adapter.shouldShowAccountsColor()) {
|
||||
itemContent.drawEnd(Utils.getAccountColor(context, account_id));
|
||||
|
@ -323,25 +409,14 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements Constan
|
|||
itemContent.drawEnd();
|
||||
}
|
||||
|
||||
profileImageView.setStyle(adapter.getProfileImageStyle());
|
||||
|
||||
if (adapter.isProfileImageEnabled()) {
|
||||
profileTypeView.setVisibility(View.VISIBLE);
|
||||
profileImageView.setVisibility(View.VISIBLE);
|
||||
loader.displayProfileImage(profileImageView, user_profile_image_url);
|
||||
} else {
|
||||
profileTypeView.setVisibility(View.GONE);
|
||||
profileImageView.setVisibility(View.GONE);
|
||||
loader.cancelDisplayTask(profileImageView);
|
||||
}
|
||||
|
||||
if (adapter.isMediaPreviewEnabled()) {
|
||||
mediaPreviewContainer.setStyle(adapter.getMediaPreviewStyle());
|
||||
mediaPreviewContainer.setVisibility(media != null && media.length > 0 ? View.VISIBLE : View.GONE);
|
||||
mediaPreviewContainer.displayMedia(media, loader, account_id, this,
|
||||
mediaPreview.setStyle(adapter.getMediaPreviewStyle());
|
||||
mediaPreview.setVisibility(media != null && media.length > 0 ? View.VISIBLE : View.GONE);
|
||||
mediaPreview.displayMedia(media, loader, account_id, this,
|
||||
adapter.getImageLoadingHandler());
|
||||
} else {
|
||||
mediaPreviewContainer.setVisibility(View.GONE);
|
||||
mediaPreview.setVisibility(View.GONE);
|
||||
}
|
||||
if (adapter.getLinkHighlightingStyle() == VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
|
||||
textView.setText(cursor.getString(indices.text_unescaped));
|
||||
|
@ -350,6 +425,7 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements Constan
|
|||
linkify.applyAllLinks(textView, account_id, getLayoutPosition(),
|
||||
cursor.getShort(indices.is_possibly_sensitive) == 1,
|
||||
adapter.getLinkHighlightingStyle());
|
||||
textView.setMovementMethod(null);
|
||||
}
|
||||
|
||||
if (reply_count > 0) {
|
||||
|
@ -372,15 +448,12 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements Constan
|
|||
} else {
|
||||
retweetCountView.setText(null);
|
||||
}
|
||||
retweetCountView.setEnabled(!user_is_protected);
|
||||
|
||||
favoriteCountView.setActivated(cursor.getInt(indices.is_favorite) == 1);
|
||||
if (twitter.isDestroyingFavorite(account_id, status_id)) {
|
||||
favoriteCountView.setActivated(false);
|
||||
favorite_count = Math.max(0, cursor.getLong(indices.favorite_count) - 1);
|
||||
} else {
|
||||
final boolean creatingFavorite = twitter.isCreatingFavorite(account_id, status_id);
|
||||
favoriteCountView.setActivated(creatingFavorite || cursor.getInt(indices.is_favorite) == 1);
|
||||
favoriteCountView.setActivated(creatingFavorite || cursor.getShort(indices.is_favorite) == 1);
|
||||
favorite_count = cursor.getLong(indices.favorite_count) + (creatingFavorite ? 1 : 0);
|
||||
}
|
||||
if (favorite_count > 0) {
|
||||
|
@ -454,8 +527,11 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements Constan
|
|||
|
||||
public void setTextSize(final float textSize) {
|
||||
nameView.setTextSize(textSize);
|
||||
quotedNameView.setTextSize(textSize);
|
||||
textView.setTextSize(textSize);
|
||||
quoteTextView.setTextSize(textSize);
|
||||
screenNameView.setTextSize(textSize * 0.85f);
|
||||
quotedScreenNameView.setTextSize(textSize * 0.85f);
|
||||
timeView.setTextSize(textSize * 0.85f);
|
||||
replyRetweetView.setTextSize(textSize * 0.75f);
|
||||
replyCountView.setTextSize(textSize);
|
||||
|
@ -465,7 +541,8 @@ public class StatusViewHolder extends RecyclerView.ViewHolder implements Constan
|
|||
|
||||
public void setupViewOptions() {
|
||||
setTextSize(adapter.getTextSize());
|
||||
mediaPreviewContainer.setStyle(adapter.getMediaPreviewStyle());
|
||||
mediaPreview.setStyle(adapter.getMediaPreviewStyle());
|
||||
profileImageView.setStyle(adapter.getProfileImageStyle());
|
||||
}
|
||||
|
||||
private void displayExtraTypeIcon(String cardName, ParcelableMedia[] media, ParcelableLocation location, String placeFullName) {
|
||||
|
|
|
@ -96,32 +96,35 @@ public interface IForegroundView {
|
|||
}
|
||||
|
||||
public void dispatchOnDraw(final Canvas canvas) {
|
||||
if (mForeground != null) {
|
||||
final Drawable foreground = mForeground;
|
||||
draw(canvas);
|
||||
}
|
||||
|
||||
if (mForegroundBoundsChanged) {
|
||||
mForegroundBoundsChanged = false;
|
||||
final Rect selfBounds = mSelfBounds;
|
||||
final Rect overlayBounds = mOverlayBounds;
|
||||
public void draw(Canvas canvas) {
|
||||
final Drawable foreground = mForeground;
|
||||
if (foreground == null) return;
|
||||
|
||||
final int w = mView.getRight() - mView.getLeft();
|
||||
final int h = mView.getBottom() - mView.getTop();
|
||||
if (mForegroundBoundsChanged) {
|
||||
mForegroundBoundsChanged = false;
|
||||
final Rect selfBounds = mSelfBounds;
|
||||
final Rect overlayBounds = mOverlayBounds;
|
||||
|
||||
if (mForegroundInPadding) {
|
||||
selfBounds.set(0, 0, w, h);
|
||||
} else {
|
||||
selfBounds.set(mView.getPaddingLeft(), mView.getPaddingTop(), w - mView.getPaddingRight(), h
|
||||
- mView.getPaddingBottom());
|
||||
}
|
||||
final int w = mView.getRight() - mView.getLeft();
|
||||
final int h = mView.getBottom() - mView.getTop();
|
||||
|
||||
final int layoutDirection = ViewCompat.getLayoutDirection(mView);
|
||||
GravityCompat.apply(mForegroundGravity, foreground.getIntrinsicWidth(),
|
||||
foreground.getIntrinsicHeight(), selfBounds, overlayBounds, layoutDirection);
|
||||
foreground.setBounds(overlayBounds);
|
||||
if (mForegroundInPadding) {
|
||||
selfBounds.set(0, 0, w, h);
|
||||
} else {
|
||||
selfBounds.set(mView.getPaddingLeft(), mView.getPaddingTop(), w - mView.getPaddingRight(), h
|
||||
- mView.getPaddingBottom());
|
||||
}
|
||||
|
||||
foreground.draw(canvas);
|
||||
final int layoutDirection = ViewCompat.getLayoutDirection(mView);
|
||||
GravityCompat.apply(mForegroundGravity, foreground.getIntrinsicWidth(),
|
||||
foreground.getIntrinsicHeight(), selfBounds, overlayBounds, layoutDirection);
|
||||
foreground.setBounds(overlayBounds);
|
||||
}
|
||||
|
||||
foreground.draw(canvas);
|
||||
}
|
||||
|
||||
public void dispatchOnLayout(final boolean changed, final int left, final int top, final int right,
|
||||
|
@ -133,35 +136,6 @@ public interface IForegroundView {
|
|||
mForegroundBoundsChanged = true;
|
||||
}
|
||||
|
||||
public void draw(final Canvas canvas) {
|
||||
if (mForeground != null) {
|
||||
final Drawable foreground = mForeground;
|
||||
|
||||
if (mForegroundBoundsChanged) {
|
||||
mForegroundBoundsChanged = false;
|
||||
final Rect selfBounds = mSelfBounds;
|
||||
final Rect overlayBounds = mOverlayBounds;
|
||||
|
||||
final int w = mView.getRight() - mView.getLeft();
|
||||
final int h = mView.getBottom() - mView.getTop();
|
||||
|
||||
if (mForegroundInPadding) {
|
||||
selfBounds.set(0, 0, w, h);
|
||||
} else {
|
||||
selfBounds.set(mView.getPaddingLeft(), mView.getPaddingTop(), w - mView.getPaddingRight(), h
|
||||
- mView.getPaddingBottom());
|
||||
}
|
||||
|
||||
final int layoutDirection = ViewCompat.getLayoutDirection(mView);
|
||||
GravityCompat.apply(mForegroundGravity, foreground.getIntrinsicWidth(),
|
||||
foreground.getIntrinsicHeight(), selfBounds, overlayBounds, layoutDirection);
|
||||
foreground.setBounds(overlayBounds);
|
||||
}
|
||||
|
||||
foreground.draw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
public void drawableStateChanged() {
|
||||
if (mForeground != null && mForeground.isStateful()) {
|
||||
mForeground.setState(mView.getDrawableState());
|
||||
|
|
|
@ -263,8 +263,8 @@
|
|||
<string name="Nitems_selected_quantity_other"><xliff:g id="items">%d</xliff:g> العناصر المحددة</string>
|
||||
<string name="view">عرض</string>
|
||||
<string name="custom_host_mapping">تعيين المضيف مخصص</string>
|
||||
<string name="host">المضيف</string>
|
||||
<string name="address">العنوان (يمكن أن يكون عنوان مضيف آخر)</string>
|
||||
<string name="host_mapping_host">المضيف</string>
|
||||
<string name="host_mapping_address">العنوان (يمكن أن يكون عنوان مضيف آخر)</string>
|
||||
<string name="dns_server">خادم DNS</string>
|
||||
<string name="activities_about_me">الاحداث المتعلقة بي</string>
|
||||
<string name="activities_by_friends">أنشطة الأصدقاء</string>
|
||||
|
|
|
@ -271,8 +271,8 @@
|
|||
<string name="view">Mostra</string>
|
||||
<string name="custom_host_mapping">Associacions de servidors personalitzades</string>
|
||||
<string name="custom_host_mapping_summary">Associa servidors com el fitxer /etc/hosts sense requerir permisos addicionals.</string>
|
||||
<string name="host">Servidor</string>
|
||||
<string name="address">Adreça (pot ser una altra adreça de servidor)</string>
|
||||
<string name="host_mapping_host">Servidor</string>
|
||||
<string name="host_mapping_address">Adreça (pot ser una altra adreça de servidor)</string>
|
||||
<string name="add_host_mapping">Afegeix una associació de servidor</string>
|
||||
<string name="tcp_dns_query">Petició DNS per TCP</string>
|
||||
<string name="tcp_dns_query_summary">Utilitza el protocol TCP per fer peticions DNS per evitar l\'«Enverinament de la Memòria Cau de DNS».</string>
|
||||
|
|
|
@ -271,8 +271,8 @@
|
|||
<string name="view">Ansicht</string>
|
||||
<string name="custom_host_mapping">Individuelles Host-Mapping</string>
|
||||
<string name="custom_host_mapping_summary">Host-Mapping wie /ect/hosts, ohne zusätzlich erforderliche Rechte.</string>
|
||||
<string name="host">Host</string>
|
||||
<string name="address">Adresse(Kann auch eine andere Host-Adresse sein)</string>
|
||||
<string name="host_mapping_host">Host</string>
|
||||
<string name="host_mapping_address">Adresse(Kann auch eine andere Host-Adresse sein)</string>
|
||||
<string name="add_host_mapping">Füge host mapping hinzu</string>
|
||||
<string name="tcp_dns_query">TCP DNS-Abfrage</string>
|
||||
<string name="tcp_dns_query_summary">Benutze TCP für DNS Anfragen, um DNS Cache Poisoning zu vermeiden.</string>
|
||||
|
|
|
@ -273,8 +273,8 @@
|
|||
<string name="view">Vista</string>
|
||||
<string name="custom_host_mapping">Asignación de host personalizado</string>
|
||||
<string name="custom_host_mapping_summary">Funciona como \"/etc/hosts\", pero no requiere permisos adicionales.</string>
|
||||
<string name="host">Host</string>
|
||||
<string name="address">Dirección (puede ser otra dirección de host)</string>
|
||||
<string name="host_mapping_host">Host</string>
|
||||
<string name="host_mapping_address">Dirección (puede ser otra dirección de host)</string>
|
||||
<string name="add_host_mapping">Añadir asignación de host</string>
|
||||
<string name="tcp_dns_query">Consulta DNS usando TCP</string>
|
||||
<string name="tcp_dns_query_summary">Utilizar el protocolo TCP para las peticiones DNS, puede evitar envenenamiento de caché DNS.</string>
|
||||
|
|
|
@ -270,8 +270,8 @@
|
|||
<string name="view">Näytä</string>
|
||||
<string name="custom_host_mapping">Mukautettu Host Mapping -määrittely</string>
|
||||
<string name="custom_host_mapping_summary">Verkkonimet määritellään kuten /etc/hosts -tiedostossa, mutta ylimääräisiä oikeuksia ei tarvita.</string>
|
||||
<string name="host">Host</string>
|
||||
<string name="address">Osoite (voi olla toinen host-osoite)</string>
|
||||
<string name="host_mapping_host">Host</string>
|
||||
<string name="host_mapping_address">Osoite (voi olla toinen host-osoite)</string>
|
||||
<string name="add_host_mapping">Lisää host mapping</string>
|
||||
<string name="tcp_dns_query">TCP DNS -kysely</string>
|
||||
<string name="tcp_dns_query_summary">Käytä TCP-yhteyskäytäntöä DNS-pyyntöihin, jotta vältyttäisiin DNS Cache Poisoning -verkkohuijauksilta.</string>
|
||||
|
|
|
@ -271,8 +271,8 @@
|
|||
<string name="view">Voir</string>
|
||||
<string name="custom_host_mapping">Mappage d\'hôte personnalisée</string>
|
||||
<string name="custom_host_mapping_summary">Mappage d\'hôte comme /etc/hosts, mais n\'exige pas de permissions supplémentaires.</string>
|
||||
<string name="host">Hôte</string>
|
||||
<string name="address">Adresse (peut-être une autre adresse hôte)</string>
|
||||
<string name="host_mapping_host">Hôte</string>
|
||||
<string name="host_mapping_address">Adresse (peut-être une autre adresse hôte)</string>
|
||||
<string name="add_host_mapping">Ajouter un hôte personnalisé</string>
|
||||
<string name="tcp_dns_query">Requête DNS TCP</string>
|
||||
<string name="tcp_dns_query_summary">Utiliser le protocole TCP pour faire des requêtes DNS, cela peut éviter un empoisonnement du cache DNS.</string>
|
||||
|
|
|
@ -243,8 +243,8 @@
|
|||
<string name="view">Nézet</string>
|
||||
<string name="custom_host_mapping">Egyedi host hozzárendelés</string>
|
||||
<string name="custom_host_mapping_summary">Host hozzárendelés, mint a /etc/hosts, de nem kell hozzá plusz jog.</string>
|
||||
<string name="host">Host</string>
|
||||
<string name="address">Cím (Lehet egy másik host címe)</string>
|
||||
<string name="host_mapping_host">Host</string>
|
||||
<string name="host_mapping_address">Cím (Lehet egy másik host címe)</string>
|
||||
<string name="add_host_mapping">Host hozzárendelés hozzáadása</string>
|
||||
<string name="tcp_dns_query">TCP DNS lekérdezés</string>
|
||||
<string name="tcp_dns_query_summary">DNS lekérdezések TCP protokoll felett, ezzel elkerülhető a DNS gyorsítótár mérgezés.</string>
|
||||
|
|
|
@ -273,8 +273,8 @@
|
|||
<string name="view">Lihat</string>
|
||||
<string name="custom_host_mapping">Kustom host mapping</string>
|
||||
<string name="custom_host_mapping_summary">Host pemetaan sperti /etc/hosts, tanpa butuh permisi tambahan.</string>
|
||||
<string name="host">Host</string>
|
||||
<string name="address">Alamat (dapat berupa alamat host lain)</string>
|
||||
<string name="host_mapping_host">Host</string>
|
||||
<string name="host_mapping_address">Alamat (dapat berupa alamat host lain)</string>
|
||||
<string name="add_host_mapping">Tambah pemetaan host</string>
|
||||
<string name="tcp_dns_query">TCP DNS Query</string>
|
||||
<string name="tcp_dns_query_summary">Gunakan protokol TCP untuk permintaan DNS dan menghindari DNS Cache Posioning.</string>
|
||||
|
|
|
@ -273,8 +273,8 @@
|
|||
<string name="view">Visualizza</string>
|
||||
<string name="custom_host_mapping">Mappatura host personalizzata</string>
|
||||
<string name="custom_host_mapping_summary">Mappa gli host come in /etc/hosts, ma non richiede permessi aggiuntivi.</string>
|
||||
<string name="host">Host</string>
|
||||
<string name="address">Indirizzo (può essere un altro indirizzo host)</string>
|
||||
<string name="host_mapping_host">Host</string>
|
||||
<string name="host_mapping_address">Indirizzo (può essere un altro indirizzo host)</string>
|
||||
<string name="add_host_mapping">Aggiungi mappatura host</string>
|
||||
<string name="tcp_dns_query">TCP DNS Query</string>
|
||||
<string name="tcp_dns_query_summary">Usa il protocollo TCP per effettuare le richieste DNS, utile per evitare il DNS Cache Poisoning.</string>
|
||||
|
|
|
@ -264,8 +264,8 @@
|
|||
<string name="view">表示</string>
|
||||
<string name="custom_host_mapping">ホストマッピングの設定</string>
|
||||
<string name="custom_host_mapping_summary">rootedでなくても/etc/hostsのようにホストマッピングができます。</string>
|
||||
<string name="host">ホスト</string>
|
||||
<string name="address">アドレス (他のホストアドレスも可)</string>
|
||||
<string name="host_mapping_host">ホスト</string>
|
||||
<string name="host_mapping_address">アドレス (他のホストアドレスも可)</string>
|
||||
<string name="add_host_mapping">ホストマッピングを追加</string>
|
||||
<string name="tcp_dns_query">TCP DNS クエリー</string>
|
||||
<string name="tcp_dns_query_summary">TCP プロトコルでDNS リクエストを通信し、DNSキャッシュ汚染を回避できます。</string>
|
||||
|
|
|
@ -270,8 +270,8 @@
|
|||
<string name="view">보기</string>
|
||||
<string name="custom_host_mapping">커스텀 호스트 매핑</string>
|
||||
<string name="custom_host_mapping_summary">/etc/hosts 에 지정하는 것처럼 호스트를 매핑합니다. 다른 권한은 전혀 필요 없습니다.</string>
|
||||
<string name="host">호스트</string>
|
||||
<string name="address">주소 (대체 호스트 주소가 될 수 있음)</string>
|
||||
<string name="host_mapping_host">호스트</string>
|
||||
<string name="host_mapping_address">주소 (대체 호스트 주소가 될 수 있음)</string>
|
||||
<string name="add_host_mapping">호스트 매핑 추가</string>
|
||||
<string name="tcp_dns_query">TCP DNS 쿼리</string>
|
||||
<string name="tcp_dns_query_summary">TCP 프로토콜로 DNS 요청을 통신하고 DNS 캐시의 오염을 막습니다.</string>
|
||||
|
|
|
@ -35,8 +35,8 @@
|
|||
<string name="show_absolute_time">Tunjukkan masa mutlak</string>
|
||||
<string name="show_absolute_time_summary">Tunjukkan masa mutlak di tweet</string>
|
||||
<string name="user_mentions">Sebutan pengguna</string>
|
||||
<string name="host">Hos</string>
|
||||
<string name="address">Alamat (Boleh jadi sebagai alamat host yang lain)</string>
|
||||
<string name="host_mapping_host">Hos</string>
|
||||
<string name="host_mapping_address">Alamat (Boleh jadi sebagai alamat host yang lain)</string>
|
||||
<string name="add_host_mapping">Tambah pemetaan hos</string>
|
||||
<string name="tcp_dns_query">TCP DNS Query</string>
|
||||
<string name="dns_server_summary">Tetapkan pelayan DNS untuk permintaan API.</string>
|
||||
|
|
|
@ -254,8 +254,8 @@
|
|||
<string name="view">Bekijk</string>
|
||||
<string name="custom_host_mapping">Aangepaste host toewijzingen</string>
|
||||
<string name="custom_host_mapping_summary">Host toewijzingen zoals /etc/hosts, maar heeft geen aanvullende rechten nodig.</string>
|
||||
<string name="host">Host</string>
|
||||
<string name="address">Adres (Kan een ander host adres zijn)</string>
|
||||
<string name="host_mapping_host">Host</string>
|
||||
<string name="host_mapping_address">Adres (Kan een ander host adres zijn)</string>
|
||||
<string name="add_host_mapping">Voeg host toewijzing toe</string>
|
||||
<string name="tcp_dns_query">TCP DNS Query</string>
|
||||
<string name="tcp_dns_query_summary">Gebruik TCP Protocol om DNS aanvragen te doen. Dit kan DNS Cache Poisoning vermijden.</string>
|
||||
|
|
|
@ -269,8 +269,8 @@
|
|||
<string name="view">Wyświetl</string>
|
||||
<string name="custom_host_mapping">Ustawianie mapowania hosta</string>
|
||||
<string name="custom_host_mapping_summary">Mapowanie hostów, nie wymaga żadnych dodatkowych uprawnień.</string>
|
||||
<string name="host">Host</string>
|
||||
<string name="address">Adres (może być inny adres hosta)</string>
|
||||
<string name="host_mapping_host">Host</string>
|
||||
<string name="host_mapping_address">Adres (może być inny adres hosta)</string>
|
||||
<string name="add_host_mapping">Dodaj mapowanie hosta</string>
|
||||
<string name="tcp_dns_query">TCP DNS Query</string>
|
||||
<string name="tcp_dns_query_summary">Używa protokołu TCP do zapytań DNS, może pozwolić uniknąć zatrucia DNS.</string>
|
||||
|
|
|
@ -256,8 +256,8 @@
|
|||
<string name="view">Ver</string>
|
||||
<string name="custom_host_mapping">Mapeamento de hosts personalizado</string>
|
||||
<string name="custom_host_mapping_summary">Mapear hosts tais como /etc/hosts, mas não requer outras permissões adicionais.</string>
|
||||
<string name="host">Host</string>
|
||||
<string name="address">Endereço (pode ser outro endereço de host)</string>
|
||||
<string name="host_mapping_host">Host</string>
|
||||
<string name="host_mapping_address">Endereço (pode ser outro endereço de host)</string>
|
||||
<string name="add_host_mapping">Adicionar mapeamento de hosts</string>
|
||||
<string name="tcp_dns_query">Consultar TCP DNS</string>
|
||||
<string name="tcp_dns_query_summary">Usar protocolo de TCP para solicitar DNS, isso pode evitar interrupções na Cache DNS.</string>
|
||||
|
|
|
@ -271,8 +271,8 @@
|
|||
<string name="view">Вид</string>
|
||||
<string name="custom_host_mapping">Перенаправление узлов</string>
|
||||
<string name="custom_host_mapping_summary">Перенаправление узлов, как с помощью /etc/hosts, но не требующее дополнительных разрешений.</string>
|
||||
<string name="host">Хост</string>
|
||||
<string name="address">Адрес (Может быть указан другой адрес)</string>
|
||||
<string name="host_mapping_host">Хост</string>
|
||||
<string name="host_mapping_address">Адрес (Может быть указан другой адрес)</string>
|
||||
<string name="add_host_mapping">Добавить перенаправление узлов</string>
|
||||
<string name="tcp_dns_query">TCP DNS-запрос</string>
|
||||
<string name="tcp_dns_query_summary">Использовать протокол TCP для запросов DNS в целях предотвращения DNS Cache Poisoning.</string>
|
||||
|
|
|
@ -244,8 +244,8 @@
|
|||
<string name="view">เปิดดู</string>
|
||||
<string name="custom_host_mapping">กำหนดที่อยู่ host เอง</string>
|
||||
<string name="custom_host_mapping_summary">กำหนดที่อยู่ host เอง (เหมือนในไฟล์ /etc/hosts) ซึ่งการกระทำนี้ไม่ต้องการสิทธิ์ใดๆ เพิ่มเติม</string>
|
||||
<string name="host">โฮสต์</string>
|
||||
<string name="address">ที่อยู่ (สามารถใช้ที่อยู่โฮสต์อื่นได้)</string>
|
||||
<string name="host_mapping_host">โฮสต์</string>
|
||||
<string name="host_mapping_address">ที่อยู่ (สามารถใช้ที่อยู่โฮสต์อื่นได้)</string>
|
||||
<string name="add_host_mapping">เพิ่มการกำหนดโฮสต์</string>
|
||||
<string name="tcp_dns_query">การสืบค้น DNS ทาง TCP</string>
|
||||
<string name="tcp_dns_query_summary">ใช้โปรโตคอล TCP เพื่อร้องขอ DNS ซึ่งสามารถหลบเลี่ยงการโจมตีแบบ DNS Cache Poisoning ได้</string>
|
||||
|
|
|
@ -273,8 +273,8 @@
|
|||
<string name="view">Görüntüle</string>
|
||||
<string name="custom_host_mapping">Özel sunucu haritalama</string>
|
||||
<string name="custom_host_mapping_summary">/etc/hosts şeklinde sunucu haritalama, ancak ekstra izin gerektirmez.</string>
|
||||
<string name="host">Sunucu</string>
|
||||
<string name="address">Adres (başka bir sunucu adresi olabilir)</string>
|
||||
<string name="host_mapping_host">Sunucu</string>
|
||||
<string name="host_mapping_address">Adres (başka bir sunucu adresi olabilir)</string>
|
||||
<string name="add_host_mapping">Sunucu haritalama ekle</string>
|
||||
<string name="tcp_dns_query">TCP DNS sorgualama</string>
|
||||
<string name="dns_server">DNS Sunucusu</string>
|
||||
|
|
|
@ -244,8 +244,8 @@
|
|||
<string name="view">Вигляд</string>
|
||||
<string name="custom_host_mapping">Перенаправлення вузлів</string>
|
||||
<string name="custom_host_mapping_summary">Перенаправлення вузлів, як за допомогою /etc/hosts, але не потребує додаткових дозволів.</string>
|
||||
<string name="host">Хост</string>
|
||||
<string name="address">Адреса (може бути інша адреса)</string>
|
||||
<string name="host_mapping_host">Хост</string>
|
||||
<string name="host_mapping_address">Адреса (може бути інша адреса)</string>
|
||||
<string name="add_host_mapping">Додати перенаправлення вузлів</string>
|
||||
<string name="tcp_dns_query">TCP DNS запит</string>
|
||||
<string name="tcp_dns_query_summary">Використовувати протокол TCP для DNS-запитів, це допоможе уникнути DNS Cache Poisoning.</string>
|
||||
|
|
|
@ -273,8 +273,8 @@
|
|||
<string name="view">查看</string>
|
||||
<string name="custom_host_mapping">自定义主机映射</string>
|
||||
<string name="custom_host_mapping_summary">如同/etc/hosts的主机映射,但不需要任何额外的权限</string>
|
||||
<string name="host">主机名</string>
|
||||
<string name="address">地址(可以是另一个主机名)</string>
|
||||
<string name="host_mapping_host">主机名</string>
|
||||
<string name="host_mapping_address">地址(可以是另一个主机名)</string>
|
||||
<string name="add_host_mapping">添加主机名映射</string>
|
||||
<string name="tcp_dns_query">TCP DNS查询方式</string>
|
||||
<string name="tcp_dns_query_summary">使用TCP协议进行DNS查询,这可以避免DNS缓存投毒</string>
|
||||
|
|
|
@ -273,8 +273,8 @@
|
|||
<string name="view">檢視</string>
|
||||
<string name="custom_host_mapping">自訂主機對應</string>
|
||||
<string name="custom_host_mapping_summary">如同/etc/hosts的主機對應,但不需要任何額外的權限</string>
|
||||
<string name="host">主機名</string>
|
||||
<string name="address">地址(可以是另一個主機名)</string>
|
||||
<string name="host_mapping_host">主機名</string>
|
||||
<string name="host_mapping_address">地址(可以是另一個主機名)</string>
|
||||
<string name="add_host_mapping">新增主機名對應</string>
|
||||
<string name="tcp_dns_query">TCP DNS 查詢方式</string>
|
||||
<string name="tcp_dns_query_summary">使用 TCP 協議進行 DNS 查詢,這可以避免 DNS 快取污染</string>
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
Binary file not shown.
After Width: | Height: | Size: 5.6 KiB |
|
@ -2,7 +2,7 @@
|
|||
<!--
|
||||
~ Twidere - Twitter client for Android
|
||||
~
|
||||
~ Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
~ Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
~
|
||||
~ This program is free software: you can redistribute it and/or modify
|
||||
~ it under the terms of the GNU General Public License as published by
|
||||
|
@ -164,20 +164,82 @@
|
|||
style="?cardActionButtonStyle"
|
||||
android:layout_width="@dimen/element_size_normal"
|
||||
android:layout_height="@dimen/element_size_normal"
|
||||
android:focusable="false"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:focusable="false"
|
||||
android:src="@drawable/ic_action_more_vertical"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<org.mariotaku.twidere.view.CardMediaContainer
|
||||
android:id="@+id/media_preview_container"
|
||||
<org.mariotaku.twidere.view.HandleSpanClickTextView
|
||||
android:id="@+id/quote_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignLeft="@+id/profile_container"
|
||||
android:layout_below="@id/profile_container"
|
||||
android:layout_marginBottom="@dimen/element_spacing_small"
|
||||
android:layout_marginTop="@dimen/element_spacing_normal"
|
||||
android:paddingLeft="@dimen/element_spacing_normal"
|
||||
android:paddingRight="@dimen/element_spacing_normal"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:visibility="gone"
|
||||
tools:text="@string/sample_status_text"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<org.mariotaku.twidere.view.ForegroundColorView
|
||||
android:id="@+id/quote_indicator"
|
||||
android:layout_width="@dimen/element_spacing_small"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBottom="@+id/text"
|
||||
android:layout_alignTop="@+id/quoted_name_container"
|
||||
android:layout_marginLeft="@dimen/element_spacing_normal"
|
||||
android:background="?android:dividerHorizontal"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/quoted_name_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/quote_text"
|
||||
android:layout_toRightOf="@+id/quote_indicator"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="@dimen/element_spacing_normal"
|
||||
android:paddingRight="@dimen/element_spacing_normal"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:id="@+id/quoted_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textStyle="bold"
|
||||
tools:text="User"/>
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:id="@+id/quoted_screen_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/element_spacing_small"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="10sp"
|
||||
tools:text="\@user"/>
|
||||
</LinearLayout>
|
||||
|
||||
<org.mariotaku.twidere.view.CardMediaContainer
|
||||
android:id="@+id/media_preview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/quoted_name_container"
|
||||
android:layout_marginTop="@dimen/element_spacing_normal"
|
||||
android:layout_toRightOf="@+id/quote_indicator"
|
||||
android:horizontalSpacing="@dimen/element_spacing_xsmall"
|
||||
android:verticalSpacing="@dimen/element_spacing_xsmall">
|
||||
|
||||
|
@ -189,10 +251,10 @@
|
|||
android:id="@+id/text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignLeft="@+id/profile_container"
|
||||
android:layout_below="@id/media_preview_container"
|
||||
android:layout_below="@id/media_preview"
|
||||
android:layout_marginBottom="@dimen/element_spacing_small"
|
||||
android:layout_marginTop="@dimen/element_spacing_normal"
|
||||
android:layout_toRightOf="@+id/quote_indicator"
|
||||
android:paddingLeft="@dimen/element_spacing_normal"
|
||||
android:paddingRight="@dimen/element_spacing_normal"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
|
|
|
@ -98,7 +98,7 @@
|
|||
android:layout_marginRight="@dimen/element_spacing_minus_small"
|
||||
android:scaleType="fitCenter"/>
|
||||
|
||||
<LinearLayout
|
||||
<RelativeLayout
|
||||
android:id="@+id/status_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -108,6 +108,7 @@
|
|||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/profile_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
|
@ -160,11 +161,71 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<org.mariotaku.twidere.view.CardMediaContainer
|
||||
android:id="@+id/media_preview_container"
|
||||
<org.mariotaku.twidere.view.HandleSpanClickTextView
|
||||
android:id="@+id/quote_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignLeft="@+id/profile_container"
|
||||
android:layout_below="@id/profile_container"
|
||||
android:layout_marginBottom="@dimen/element_spacing_small"
|
||||
android:layout_marginTop="@dimen/element_spacing_normal"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:visibility="gone"
|
||||
tools:text="@string/sample_status_text"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<org.mariotaku.twidere.view.ForegroundColorView
|
||||
android:id="@+id/quote_indicator"
|
||||
android:layout_width="@dimen/element_spacing_small"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBottom="@+id/text"
|
||||
android:layout_alignTop="@+id/quoted_name_container"
|
||||
android:layout_marginRight="@dimen/element_spacing_normal"
|
||||
android:background="?android:dividerHorizontal"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/quoted_name_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/quote_text"
|
||||
android:layout_toRightOf="@+id/quote_indicator"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:id="@+id/quoted_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textStyle="bold"
|
||||
tools:text="User"/>
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:id="@+id/quoted_screen_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/element_spacing_small"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:textAppearanceSmall"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="10sp"
|
||||
tools:text="\@user"/>
|
||||
</LinearLayout>
|
||||
|
||||
<org.mariotaku.twidere.view.CardMediaContainer
|
||||
android:id="@+id/media_preview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/quoted_name_container"
|
||||
android:layout_marginTop="@dimen/element_spacing_small"
|
||||
android:layout_toRightOf="@+id/quote_indicator"
|
||||
android:horizontalSpacing="@dimen/element_spacing_xsmall"
|
||||
android:verticalSpacing="@dimen/element_spacing_xsmall">
|
||||
|
||||
|
@ -176,12 +237,14 @@
|
|||
android:id="@+id/text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/media_preview"
|
||||
android:layout_marginTop="@dimen/element_spacing_small"
|
||||
android:layout_toRightOf="@+id/quote_indicator"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
tools:text="@string/sample_status_text"/>
|
||||
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
android:id="@+id/host"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/host"
|
||||
android:hint="@string/host_mapping_host"
|
||||
android:inputType="text|textUri"
|
||||
android:singleLine="true"/>
|
||||
|
||||
|
@ -44,7 +44,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:hint="@string/address"
|
||||
android:hint="@string/host_mapping_address"
|
||||
android:inputType="text|textUri"
|
||||
android:singleLine="true"/>
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<org.mariotaku.twidere.view.TouchImageView
|
||||
<com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
|
||||
android:id="@+id/image_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Twidere - Twitter client for Android
|
||||
~
|
||||
~ Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
~
|
||||
~ This program is free software: you can redistribute it and/or modify
|
||||
~ it under the terms of the GNU General Public License as published by
|
||||
~ the Free Software Foundation, either version 3 of the License, or
|
||||
~ (at your option) any later version.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
~ GNU General Public License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License
|
||||
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<org.mariotaku.twidere.view.SquareRelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<org.mariotaku.twidere.view.HighlightImageView
|
||||
android:id="@+id/media_preview_item"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_centerInParent="true"
|
||||
android:scaleType="centerCrop"/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/media_preview_progress"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_margin="16dp"/>
|
||||
|
||||
</org.mariotaku.twidere.view.SquareRelativeLayout>
|
|
@ -20,7 +20,6 @@
|
|||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="?android:actionBarSize"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:activatedBackgroundIndicator"
|
||||
|
|
|
@ -182,7 +182,6 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"/>
|
||||
|
||||
|
||||
<org.mariotaku.twidere.view.themed.ThemedTextView
|
||||
android:id="@+id/location_view"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:contentDescription="@string/media"
|
||||
android:foreground="@drawable/ic_action_play_circle"
|
||||
android:foregroundGravity="center"
|
||||
android:scaleType="centerCrop"/>
|
||||
|
||||
|
|
|
@ -19,16 +19,23 @@
|
|||
-->
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/media_preview"
|
||||
android:id="@+id/media_preview_container"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/media_preview_grid"
|
||||
<org.mariotaku.twidere.view.CardMediaContainer
|
||||
android:id="@+id/media_preview"
|
||||
android:layout_width="match_parent"
|
||||
android:gravity="center"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"/>
|
||||
android:layout_marginTop="@dimen/element_spacing_normal"
|
||||
android:horizontalSpacing="@dimen/element_spacing_xsmall"
|
||||
android:verticalSpacing="@dimen/element_spacing_xsmall">
|
||||
|
||||
<include layout="@layout/layout_card_media_preview"/>
|
||||
|
||||
</org.mariotaku.twidere.view.CardMediaContainer>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/media_preview_load"
|
||||
|
|
|
@ -23,21 +23,16 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:descendantFocusability="blocksDescendants"
|
||||
android:divider="?android:dividerHorizontal"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
android:orientation="horizontal"
|
||||
android:showDividers="middle">
|
||||
|
||||
<Switch
|
||||
android:id="@android:id/toggle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<View
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="@dimen/element_size_normal"
|
||||
android:layout_marginLeft="@dimen/element_spacing_small"
|
||||
android:layout_marginRight="@dimen/element_spacing_small"
|
||||
android:background="?android:dividerHorizontal"/>
|
||||
|
||||
<org.mariotaku.twidere.view.ActionIconButton
|
||||
android:id="@+id/settings"
|
||||
android:layout_width="@dimen/element_size_normal"
|
||||
|
|
|
@ -273,8 +273,8 @@
|
|||
<string name="view">View</string>
|
||||
<string name="custom_host_mapping">Custom host mapping</string>
|
||||
<string name="custom_host_mapping_summary">Host mapping like /etc/hosts, but does not require any additional permissions.</string>
|
||||
<string name="host">Host</string>
|
||||
<string name="address">Address (Can be another host address)</string>
|
||||
<string name="host_mapping_host">Host</string>
|
||||
<string name="host_mapping_address">Address (Can be another host address)</string>
|
||||
<string name="add_host_mapping">Add host mapping</string>
|
||||
<string name="tcp_dns_query">TCP DNS Query</string>
|
||||
<string name="tcp_dns_query_summary">Use TCP Protocol to make DNS requests, which can avoid DNS Cache Poisoning.</string>
|
||||
|
@ -739,6 +739,9 @@
|
|||
<string name="permission_label_shorten_status">Shorten tweet</string>
|
||||
<string name="permission_label_upload_media">Upload media</string>
|
||||
<string name="permission_label_sync_timeline">Sync timeline</string>
|
||||
<string name="thumbor_integration">Thumbor integration</string>
|
||||
<string name="server_address">Server address</string>
|
||||
<string name="security_key">Security key</string>
|
||||
|
||||
|
||||
</resources>
|
|
@ -64,6 +64,12 @@
|
|||
<org.mariotaku.twidere.preference.DefaultAPIPreference
|
||||
android:summary="@string/default_api_settings_summary"
|
||||
android:title="@string/default_api_settings"/>
|
||||
|
||||
<org.mariotaku.twidere.preference.SwitchSettingsDetailsPreference
|
||||
android:defaultValue="false"
|
||||
android:key="thumbor_enabled"
|
||||
android:src="@xml/preferences_thumbor"
|
||||
android:title="@string/thumbor_integration"/>
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Twidere - Twitter client for Android
|
||||
~
|
||||
~ Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
~
|
||||
~ This program is free software: you can redistribute it and/or modify
|
||||
~ it under the terms of the GNU General Public License as published by
|
||||
~ the Free Software Foundation, either version 3 of the License, or
|
||||
~ (at your option) any later version.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
~ GNU General Public License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License
|
||||
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:title="@string/thumbor_integration">
|
||||
|
||||
<org.mariotaku.twidere.preference.AutoFixEditTextPreference
|
||||
android:inputType="textUri"
|
||||
android:key="thumbor_address"
|
||||
android:title="@string/server_address"/>
|
||||
<org.mariotaku.twidere.preference.AutoFixEditTextPreference
|
||||
android:inputType="textVisiblePassword"
|
||||
android:key="thumbor_security_key"
|
||||
android:title="@string/security_key"/>
|
||||
|
||||
</PreferenceScreen>
|
Loading…
Reference in New Issue