updated libraries

This commit is contained in:
Mariotaku Lee 2016-08-20 18:59:10 +08:00
parent dcc4487018
commit f64c706939
18 changed files with 436 additions and 186 deletions

View File

@ -7,7 +7,7 @@ buildscript {
maven { url 'https://plugins.gradle.org/m2/' }
}
dependencies {
classpath 'com.github.ben-manes:gradle-versions-plugin:0.12.0'
classpath 'com.github.ben-manes:gradle-versions-plugin:0.13.0'
classpath 'com.android.tools.build:gradle:2.1.3'
classpath 'com.google.gms:google-services:3.0.0'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'

View File

@ -41,8 +41,8 @@ dependencies {
apt 'com.github.mariotaku.ObjectCursor:processor:0.9.9'
compile 'com.android.support:support-annotations:24.2.0'
compile 'com.bluelinelabs:logansquare:1.3.7'
compile 'com.github.mariotaku.RestFu:library:0.9.32'
compile 'com.github.mariotaku.RestFu:oauth:0.9.32'
compile 'com.github.mariotaku.RestFu:library:0.9.33'
compile 'com.github.mariotaku.RestFu:oauth:0.9.33'
compile 'com.hannesdorfmann.parcelableplease:annotation:1.0.2'
compile 'com.github.mariotaku.ObjectCursor:core:0.9.9'
compile 'com.github.mariotaku.CommonsLibrary:objectcursor:0.9.8'

View File

@ -19,13 +19,6 @@
package org.mariotaku.microblog.library.twitter.api;
import org.mariotaku.restfu.annotation.method.GET;
import org.mariotaku.restfu.annotation.method.POST;
import org.mariotaku.restfu.annotation.param.KeyValue;
import org.mariotaku.restfu.annotation.param.Param;
import org.mariotaku.restfu.annotation.param.Queries;
import org.mariotaku.restfu.annotation.param.Query;
import org.mariotaku.restfu.http.BodyType;
import org.mariotaku.microblog.library.MicroBlogException;
import org.mariotaku.microblog.library.twitter.model.Friendship;
import org.mariotaku.microblog.library.twitter.model.FriendshipUpdate;
@ -35,6 +28,14 @@ import org.mariotaku.microblog.library.twitter.model.Paging;
import org.mariotaku.microblog.library.twitter.model.Relationship;
import org.mariotaku.microblog.library.twitter.model.ResponseList;
import org.mariotaku.microblog.library.twitter.model.User;
import org.mariotaku.microblog.library.twitter.template.UserAnnotationTemplate;
import org.mariotaku.restfu.annotation.method.GET;
import org.mariotaku.restfu.annotation.method.POST;
import org.mariotaku.restfu.annotation.param.KeyValue;
import org.mariotaku.restfu.annotation.param.Param;
import org.mariotaku.restfu.annotation.param.Queries;
import org.mariotaku.restfu.annotation.param.Query;
import org.mariotaku.restfu.http.BodyType;
@SuppressWarnings("RedundantThrows")
@Queries({@KeyValue(key = "include_entities", valueKey = "include_entities")})
@ -42,26 +43,32 @@ public interface FriendsFollowersResources {
@POST("/friendships/create.json")
@BodyType(BodyType.FORM)
@Queries(template = UserAnnotationTemplate.class)
User createFriendship(@Param("user_id") String userId) throws MicroBlogException;
@POST("/friendships/create.json")
@BodyType(BodyType.FORM)
@Queries(template = UserAnnotationTemplate.class)
User createFriendship(@Param("user_id") String userId, @Param("follow") boolean follow) throws MicroBlogException;
@POST("/friendships/create.json")
@BodyType(BodyType.FORM)
@Queries(template = UserAnnotationTemplate.class)
User createFriendshipByScreenName(@Param("screen_name") String screenName) throws MicroBlogException;
@POST("/friendships/create.json")
@BodyType(BodyType.FORM)
@Queries(template = UserAnnotationTemplate.class)
User createFriendshipByScreenName(@Param("screen_name") String screenName, @Param("follow") boolean follow) throws MicroBlogException;
@POST("/friendships/destroy.json")
@BodyType(BodyType.FORM)
@Queries(template = UserAnnotationTemplate.class)
User destroyFriendship(@Param("user_id") String userId) throws MicroBlogException;
@POST("/friendships/destroy.json")
@BodyType(BodyType.FORM)
@Queries(template = UserAnnotationTemplate.class)
User destroyFriendshipByScreenName(@Param("screen_name") String screenName) throws MicroBlogException;
@GET("/followers/ids.json")

View File

@ -19,13 +19,6 @@
package org.mariotaku.microblog.library.twitter.api;
import org.mariotaku.microblog.library.twitter.template.StatusAnnotationTemplate;
import org.mariotaku.restfu.annotation.method.GET;
import org.mariotaku.restfu.annotation.method.POST;
import org.mariotaku.restfu.annotation.param.KeyValue;
import org.mariotaku.restfu.annotation.param.Param;
import org.mariotaku.restfu.annotation.param.Queries;
import org.mariotaku.restfu.annotation.param.Query;
import org.mariotaku.microblog.library.MicroBlogException;
import org.mariotaku.microblog.library.twitter.model.PageableResponseList;
import org.mariotaku.microblog.library.twitter.model.Paging;
@ -34,6 +27,13 @@ import org.mariotaku.microblog.library.twitter.model.Status;
import org.mariotaku.microblog.library.twitter.model.User;
import org.mariotaku.microblog.library.twitter.model.UserList;
import org.mariotaku.microblog.library.twitter.model.UserListUpdate;
import org.mariotaku.microblog.library.twitter.template.StatusAnnotationTemplate;
import org.mariotaku.microblog.library.twitter.template.UserAnnotationTemplate;
import org.mariotaku.restfu.annotation.method.GET;
import org.mariotaku.restfu.annotation.method.POST;
import org.mariotaku.restfu.annotation.param.Param;
import org.mariotaku.restfu.annotation.param.Queries;
import org.mariotaku.restfu.annotation.param.Query;
public interface ListResources {
@POST("/lists/members/create.json")
@ -73,15 +73,18 @@ public interface ListResources {
UserList destroyUserListSubscription(@Param("list_id") String listId) throws MicroBlogException;
@GET("/lists/members.json")
@Queries(template = UserAnnotationTemplate.class)
PageableResponseList<User> getUserListMembers(@Query("list_id") String listId, @Query Paging paging) throws MicroBlogException;
@GET("/lists/members.json")
@Queries(template = UserAnnotationTemplate.class)
PageableResponseList<User> getUserListMembers(@Query("slug") String slug,
@Query("owner_id") String ownerId,
@Query Paging paging)
throws MicroBlogException;
@GET("/lists/members.json")
@Queries(template = UserAnnotationTemplate.class)
PageableResponseList<User> getUserListMembersByScreenName(@Query("slug") String slug, @Query("owner_screen_name") String ownerScreenName, @Query Paging paging)
throws MicroBlogException;
@ -130,13 +133,16 @@ public interface ListResources {
throws MicroBlogException;
@GET("/lists/subscribers.json")
@Queries(template = UserAnnotationTemplate.class)
PageableResponseList<User> getUserListSubscribers(@Query("list_id") String listId, @Query Paging paging) throws MicroBlogException;
@GET("/lists/subscribers.json")
@Queries(template = UserAnnotationTemplate.class)
PageableResponseList<User> getUserListSubscribers(@Query("list_id") String slug, @Query("owner_id") String ownerId, @Query Paging paging)
throws MicroBlogException;
@GET("/lists/subscribers.json")
@Queries(template = UserAnnotationTemplate.class)
PageableResponseList<User> getUserListSubscribersByScreenName(@Query("list_id") String slug, @Query("owner_screen_name") String ownerScreenName, @Query Paging paging)
throws MicroBlogException;

View File

@ -19,14 +19,6 @@
package org.mariotaku.microblog.library.twitter.api;
import org.mariotaku.restfu.annotation.method.GET;
import org.mariotaku.restfu.annotation.method.POST;
import org.mariotaku.restfu.annotation.param.KeyValue;
import org.mariotaku.restfu.annotation.param.Param;
import org.mariotaku.restfu.annotation.param.Queries;
import org.mariotaku.restfu.annotation.param.Query;
import org.mariotaku.restfu.http.BodyType;
import org.mariotaku.restfu.http.mime.FileBody;
import org.mariotaku.microblog.library.MicroBlogException;
import org.mariotaku.microblog.library.twitter.model.AccountSettings;
import org.mariotaku.microblog.library.twitter.model.Category;
@ -38,11 +30,17 @@ import org.mariotaku.microblog.library.twitter.model.ResponseCode;
import org.mariotaku.microblog.library.twitter.model.ResponseList;
import org.mariotaku.microblog.library.twitter.model.SettingsUpdate;
import org.mariotaku.microblog.library.twitter.model.User;
import org.mariotaku.microblog.library.twitter.template.UserAnnotationTemplate;
import org.mariotaku.restfu.annotation.method.GET;
import org.mariotaku.restfu.annotation.method.POST;
import org.mariotaku.restfu.annotation.param.Param;
import org.mariotaku.restfu.annotation.param.Queries;
import org.mariotaku.restfu.annotation.param.Query;
import org.mariotaku.restfu.http.BodyType;
import org.mariotaku.restfu.http.mime.FileBody;
@SuppressWarnings("RedundantThrows")
@Queries({@KeyValue(key = "include_entities", valueKey = "include_entities"),
@KeyValue(key = "include_cards", valueKey = "include_cards"),
@KeyValue(key = "cards_platform", valueKey = "cards_platform")})
@Queries(template = UserAnnotationTemplate.class)
public interface UsersResources {
@POST("/blocks/create.json")

View File

@ -70,4 +70,12 @@ public class SettingsUpdate extends SimpleValueMap {
put("screen_name", screenName);
}
public void setUniversalQualityFiltering(boolean enabled) {
put("universal_quality_filtering", enabled ? "enabled" : "disabled");
}
public void setSmartMute(boolean enabled) {
put("smart_mute", enabled ? "enabled" : "disabled");
}
}

View File

@ -19,6 +19,9 @@
package org.mariotaku.microblog.library.twitter.model;
import android.support.annotation.StringDef;
import org.mariotaku.microblog.library.twitter.util.InternalArrayUtil;
import org.mariotaku.restfu.http.SimpleValueMap;
/**
@ -39,6 +42,49 @@ public class UniversalSearchQuery extends SimpleValueMap {
}
public void setModules(String[] modules) {
put("modules", modules);
put("modules", InternalArrayUtil.join(modules, ","));
}
public void setFilter(@Filter String filter) {
put("filter", filter);
}
public void setResultType(@ResultType String resultType) {
put("result_type", resultType);
}
public void setNear(GeoLocation location) {
put("near", location.getLatitude() + "," + location.getLongitude());
}
@StringDef({Filter.IMAGES, Filter.VIDEOS, Filter.PERISCOPE, Filter.NEWS})
public @interface Filter {
String IMAGES = "images";
String VIDEOS = "videos";
String PERISCOPE = "periscope";
String NEWS = "news";
}
@StringDef({Module.TWEET, Module.USER_GALLERY, Module.NEWS, Module.MEDIA_GALLERY,
Module.SUGGESTION, Module.EVENT, Module.TWEET_GALLERY, Module.FOLLOWS_TWEET_GALLERY,
Module.NEARBY_TWEET_GALLERY, Module.SUMMARY, Module.EVENT_SUMMARY})
public @interface Module {
String TWEET = "tweet";
String USER_GALLERY = "user_gallery";
String NEWS = "news";
String MEDIA_GALLERY = "media_gallery";
String SUGGESTION = "suggestion";
String EVENT = "event";
String TWEET_GALLERY = "tweet_gallery";
String FOLLOWS_TWEET_GALLERY = "follows_tweet_gallery";
String NEARBY_TWEET_GALLERY = "nearby_tweet_gallery";
String SUMMARY = "summary";
String EVENT_SUMMARY = "event_summary";
}
@StringDef({ResultType.RECENT, ResultType.FOLLOWS})
public @interface ResultType {
String RECENT = "recent";
String FOLLOWS = "follows";
}
}

View File

@ -19,8 +19,18 @@
package org.mariotaku.microblog.library.twitter.model;
import android.support.annotation.StringDef;
import com.bluelinelabs.logansquare.annotation.JsonField;
import com.bluelinelabs.logansquare.annotation.JsonObject;
import com.bluelinelabs.logansquare.typeconverters.TypeConverter;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Created by mariotaku on 15/10/21.
@ -46,6 +56,21 @@ public class UniversalSearchResult {
StatusModule status;
@JsonField(name = "user_gallery")
UserGalleryModule userGallery;
@JsonField(name = "suggestion")
SuggestionModule suggestion;
public StatusModule getStatus() {
return status;
}
public UserGalleryModule getUserGallery() {
return userGallery;
}
public SuggestionModule getSuggestion() {
return suggestion;
}
}
@JsonObject
@ -68,30 +93,34 @@ public class UniversalSearchResult {
@JsonField(name = "social_context")
SocialContext socialContext;
@JsonField(name = "result_type")
String resultType;
@JsonField(name = "auto_expand")
boolean autoExpand;
@JsonField(name = "result_type")
@ModuleMetadata.ResultType
String resultType;
public SocialContext getSocialContext() {
return socialContext;
}
public String getResultType() {
return resultType;
}
public boolean isAutoExpand() {
return autoExpand;
}
@ModuleMetadata.ResultType
public final String getResultType() {
return resultType;
}
@JsonObject
public static class SocialContext {
@JsonField(name = "following")
boolean following;
@JsonField(name = "followed_by")
boolean followedBy;
@JsonField(name = "related_users")
RelatedUsers relatedUsers;
public boolean isFollowing() {
return following;
@ -100,6 +129,37 @@ public class UniversalSearchResult {
public boolean isFollowedBy() {
return followedBy;
}
public RelatedUsers getRelatedUsers() {
return relatedUsers;
}
@JsonObject
public static class RelatedUsers {
@JsonField(name = "follow_and_follow")
FollowAndFollow followAndFollow;
@JsonObject
public static class FollowAndFollow {
@JsonField(name = "users")
MiniUser[] users;
@JsonField(name = "num_more_users")
int numMoreUsers;
}
@JsonObject
public static class MiniUser {
@JsonField(name = "id_string")
String id;
@JsonField(name = "name")
String name;
@JsonField(name = "screen_name")
String screenName;
}
}
}
}
}
@ -126,10 +186,100 @@ public class UniversalSearchResult {
}
}
@JsonObject
public static class SuggestionModule {
@JsonField(name = "metadata")
ModuleMetadata metadata;
@JsonField(name = "data")
SuggestionData data;
public ModuleMetadata getMetadata() {
return metadata;
}
public SuggestionData getData() {
return data;
}
@JsonObject
public static class SuggestionData {
@JsonField(name = "suggestion_type")
String suggestionType;
@JsonField(name = "suggestions")
Suggestion[] suggestions;
public String getSuggestionType() {
return suggestionType;
}
public Suggestion[] getSuggestions() {
return suggestions;
}
@JsonObject
public static class Suggestion {
@JsonField(name = "query")
String query;
@JsonField(name = "indices", typeConverter = Index.ArrayConverter.class)
Index[] indices;
public String getQuery() {
return query;
}
public static class Index {
int start;
int end;
public static class ArrayConverter implements TypeConverter<Index[]> {
@Override
public Index[] parse(JsonParser jsonParser) throws IOException {
if (jsonParser.getCurrentToken() == null) {
jsonParser.nextToken();
}
if (jsonParser.getCurrentToken() != JsonToken.START_ARRAY) {
jsonParser.skipChildren();
return null;
}
List<Index> list = new ArrayList<>();
while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
Index index = new Index();
index.start = jsonParser.nextIntValue(-1);
index.end = jsonParser.nextIntValue(-1);
list.add(index);
}
return list.toArray(new Index[list.size()]);
}
@Override
public void serialize(Index[] indices, String fieldName,
boolean writeFieldNameForObject,
JsonGenerator jsonGenerator) throws IOException {
if (writeFieldNameForObject) {
jsonGenerator.writeFieldName(fieldName);
}
if (indices == null) {
jsonGenerator.writeNull();
} else {
jsonGenerator.writeStartArray();
for (Index index : indices) {
jsonGenerator.writeNumber(index.start);
jsonGenerator.writeNumber(index.end);
}
jsonGenerator.writeEndArray();
}
}
}
}
}
}
}
@JsonObject
public static class UserModule {
@JsonField(name = "metadata")
Object metadata;
ModuleMetadata metadata;
@JsonField(name = "data")
User data;
@ -141,11 +291,6 @@ public class UniversalSearchResult {
return data;
}
@JsonObject
public static class Metadata {
@JsonField(name = "result_type")
String resultType;
}
}
@JsonObject
@ -157,4 +302,23 @@ public class UniversalSearchResult {
return cursor;
}
}
@JsonObject
public static class ModuleMetadata {
@JsonField(name = "result_type")
@ResultType
String resultType;
@ResultType
public final String getResultType() {
return resultType;
}
@StringDef({ResultType.NORMAL, ResultType.TOP})
public @interface ResultType {
String NORMAL = "normal";
String TOP = "top";
}
}
}

View File

@ -15,7 +15,9 @@ import org.mariotaku.restfu.annotation.param.Queries;
@KeyValue(key = "include_descendent_reply_count", valueKey = "include_descendent_reply_count"),
@KeyValue(key = "include_ext_alt_text", valueKey = "include_ext_alt_text"),
@KeyValue(key = "tweet_mode", valueKey = "tweet_mode"),
@KeyValue(key = "model_version", valueKey = "model_version")
@KeyValue(key = "model_version", valueKey = "model_version"),
@KeyValue(key = "include_blocking", value = "true"),
@KeyValue(key = "include_blocked_by", value = "true")
})
public class StatusAnnotationTemplate {
}

View File

@ -0,0 +1,15 @@
package org.mariotaku.microblog.library.twitter.template;
import org.mariotaku.restfu.annotation.param.KeyValue;
import org.mariotaku.restfu.annotation.param.Queries;
/**
* Created by mariotaku on 16/8/20.
*/
@Queries({@KeyValue(key = "include_entities", valueKey = "include_entities"),
@KeyValue(key = "include_cards", valueKey = "include_cards"),
@KeyValue(key = "cards_platform", valueKey = "cards_platform"),
@KeyValue(key = "include_blocking", value = "true"),
@KeyValue(key = "include_blocked_by", value = "true")})
public class UserAnnotationTemplate {
}

View File

@ -0,0 +1,19 @@
package org.mariotaku.microblog.library.twitter.util;
/**
* Created by mariotaku on 16/8/20.
*/
public class InternalArrayUtil {
public static String join(Object[] array, String separator) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < array.length; i++) {
if (i != 0) {
sb.append(separator);
}
sb.append(array[i]);
}
return sb.toString();
}
}

View File

@ -21,7 +21,7 @@ buildscript {
dependencies {
// START Non-FOSS component
classpath 'io.fabric.tools:gradle:1.21.5'
classpath 'io.fabric.tools:gradle:1.21.7'
// END Non-FOSS component
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
@ -90,7 +90,7 @@ dependencies {
// wearApp project(':twidere.wear')
kapt 'com.bluelinelabs:logansquare-compiler:1.3.7'
kapt 'com.hannesdorfmann.parcelableplease:processor:1.0.2'
kapt 'com.google.dagger:dagger-compiler:2.1'
kapt 'com.google.dagger:dagger-compiler:2.6'
kapt 'com.github.mariotaku.ObjectCursor:processor:0.9.9'
compile('com.github.mariotaku:app-theme-engine:1efc6237e1@aar') {
@ -105,11 +105,11 @@ dependencies {
googleCompile 'com.google.android.gms:play-services-maps:9.4.0'
googleCompile 'com.google.android.gms:play-services-auth:9.4.0'
googleCompile 'com.google.maps.android:android-maps-utils:0.4.3'
googleCompile('com.crashlytics.sdk.android:crashlytics:2.5.5@aar') { transitive = true }
googleCompile('com.crashlytics.sdk.android:crashlytics:2.6.2@aar') { transitive = true }
googleCompile ':YouTubeAndroidPlayerApi:1.2.2@jar'
// END Non-FOSS component
fdroidCompile 'org.osmdroid:osmdroid-android:5.1'
fdroidCompile 'org.osmdroid:osmdroid-android:5.2'
debugCompile 'com.facebook.stetho:stetho:1.3.1'
debugCompile 'com.facebook.stetho:stetho-okhttp3:1.3.1'
@ -155,13 +155,13 @@ dependencies {
compile 'com.github.mariotaku:PickNCrop:0.9.4'
compile 'com.github.mariotaku.RestFu:library:0.9.33'
compile 'com.github.mariotaku.RestFu:okhttp3:0.9.33'
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.squareup.okhttp3:okhttp:3.4.1'
compile 'com.lnikkila:extendedtouchview:0.1.0'
compile 'com.google.dagger:dagger:2.1'
compile 'org.attoparser:attoparser:1.4.0.RELEASE'
compile 'com.google.dagger:dagger:2.6'
compile 'org.attoparser:attoparser:2.0.0.RELEASE'
compile 'com.github.mariotaku.MediaViewerLibrary:base:0.9.17'
compile 'com.github.mariotaku.MediaViewerLibrary:subsample-image-view:0.9.17'
compile 'com.github.mariotaku.SQLiteQB:library:0.9.6'
compile 'com.github.mariotaku.SQLiteQB:library:0.9.7'
compile 'com.github.mariotaku.ObjectCursor:core:0.9.9'
compile 'com.github.mariotaku:MultiValueSwitch:0.9.7'
compile 'com.github.mariotaku:AbstractTask:0.9.4'

View File

@ -36,7 +36,7 @@ import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.Toast;
import org.attoparser.AttoParseException;
import org.attoparser.ParseException;
import org.mariotaku.microblog.library.MicroBlogException;
import org.mariotaku.microblog.library.twitter.TwitterOAuth;
import org.mariotaku.restfu.http.Authorization;
@ -135,7 +135,7 @@ public class BrowserSignInActivity extends BaseActivity {
OAuthPasswordAuthenticator.OAuthPinData data = new OAuthPasswordAuthenticator.OAuthPinData();
OAuthPasswordAuthenticator.Companion.readOAuthPINFromHtml(new StringReader(html), data);
return data.getOauthPin();
} catch (final AttoParseException | IOException e) {
} catch (final ParseException | IOException e) {
Log.w(LOGTAG, e);
}
return null;

View File

@ -27,12 +27,10 @@ import android.text.style.StyleSpan;
import android.text.style.URLSpan;
import org.apache.commons.lang3.StringUtils;
import org.attoparser.AttoParseException;
import org.attoparser.IAttoParser;
import org.attoparser.markup.MarkupAttoParser;
import org.attoparser.markup.html.AbstractStandardNonValidatingHtmlAttoHandler;
import org.attoparser.markup.html.HtmlParsingConfiguration;
import org.attoparser.markup.html.elements.IHtmlElement;
import org.attoparser.ParseException;
import org.attoparser.config.ParseConfiguration;
import org.attoparser.simple.AbstractSimpleMarkupHandler;
import org.attoparser.simple.SimpleMarkupParser;
import java.util.ArrayList;
import java.util.List;
@ -44,18 +42,17 @@ import java.util.Map;
*/
public class HtmlSpanBuilder {
private static final IAttoParser PARSER = new MarkupAttoParser();
private static final SimpleMarkupParser PARSER = new SimpleMarkupParser(ParseConfiguration.htmlConfiguration());
private HtmlSpanBuilder() {
}
public static Spannable fromHtml(String html) throws ParseException {
final HtmlParsingConfiguration conf = new HtmlParsingConfiguration();
final HtmlSpanHandler handler = new HtmlSpanHandler(conf);
public static Spannable fromHtml(String html) throws HtmlParseException {
final HtmlSpanHandler handler = new HtmlSpanHandler();
try {
PARSER.parse(html, handler);
} catch (AttoParseException e) {
throw new ParseException(e);
} catch (ParseException e) {
throw new HtmlParseException(e);
}
return handler.getText();
}
@ -63,7 +60,7 @@ public class HtmlSpanBuilder {
public static CharSequence fromHtml(String html, CharSequence fallback) {
try {
return fromHtml(html);
} catch (ParseException e) {
} catch (HtmlParseException e) {
return fallback;
}
}
@ -106,20 +103,20 @@ public class HtmlSpanBuilder {
return -1;
}
public static class ParseException extends RuntimeException {
public ParseException() {
public static class HtmlParseException extends RuntimeException {
public HtmlParseException() {
super();
}
public ParseException(String detailMessage) {
public HtmlParseException(String detailMessage) {
super(detailMessage);
}
public ParseException(String detailMessage, Throwable throwable) {
public HtmlParseException(String detailMessage, Throwable throwable) {
super(detailMessage, throwable);
}
public ParseException(Throwable throwable) {
public HtmlParseException(Throwable throwable) {
super(throwable);
}
}
@ -140,23 +137,22 @@ public class HtmlSpanBuilder {
}
}
static class HtmlSpanHandler extends AbstractStandardNonValidatingHtmlAttoHandler {
static class HtmlSpanHandler extends AbstractSimpleMarkupHandler {
private final SpannableStringBuilder sb;
List<TagInfo> tagInfo;
public HtmlSpanHandler(HtmlParsingConfiguration conf) {
super(conf);
public HtmlSpanHandler() {
sb = new SpannableStringBuilder();
tagInfo = new ArrayList<>();
}
@Override
public void handleText(char[] buffer, int offset, int len, int line, int col) throws AttoParseException {
public void handleText(char[] buffer, int offset, int len, int line, int col) {
sb.append(HtmlEscapeHelper.unescape(new String(buffer, offset, len)));
}
@Override
public void handleHtmlCloseElement(IHtmlElement element, String elementName, int line, int col) throws AttoParseException {
public void handleCloseElement(String elementName, int line, int col) {
final int lastIndex = lastIndexOfTag(tagInfo, elementName);
if (lastIndex != -1) {
TagInfo info = tagInfo.get(lastIndex);
@ -166,7 +162,7 @@ public class HtmlSpanBuilder {
}
@Override
public void handleHtmlOpenElement(IHtmlElement element, String elementName, Map<String, String> attributes, int line, int col) throws AttoParseException {
public void handleOpenElement(String elementName, Map<String, String> attributes, int line, int col) {
tagInfo.add(new TagInfo(sb.length(), elementName, attributes));
}

View File

@ -78,8 +78,10 @@ abstract class AbsContentRecyclerViewFragment<A : LoadMoreSupportAdapter<Recycle
updateRefreshProgressOffset()
}
override fun onRefresh() {
triggerRefresh()
override final fun onRefresh() {
if (!triggerRefresh()) {
refreshing = false
}
}
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
@ -237,7 +239,7 @@ abstract class AbsContentRecyclerViewFragment<A : LoadMoreSupportAdapter<Recycle
override fun fitSystemWindows(insets: Rect) {
val extraPadding = extraContentPadding
recyclerView!!.setPadding(insets.left + extraPadding.left, insets.top + extraPadding.top,
recyclerView.setPadding(insets.left + extraPadding.left, insets.top + extraPadding.top,
insets.right + extraPadding.right, insets.bottom + extraPadding.bottom)
errorContainer.setPadding(insets.left, insets.top, insets.right, insets.bottom)
progressContainer.setPadding(insets.left, insets.top, insets.right, insets.bottom)

View File

@ -119,62 +119,6 @@ abstract class CursorStatusesFragment : AbsStatusesFragment() {
}
}
protected inner class CursorStatusesBusCallback {
@Subscribe
fun notifyGetStatusesTaskChanged(event: GetStatusesTaskEvent) {
if (event.uri != contentUri) return
refreshing = event.running
if (!event.running) {
setLoadMoreIndicatorPosition(ILoadMoreSupportAdapter.NONE)
refreshEnabled = true
showContentOrError()
}
}
@Subscribe
fun notifyFavoriteTask(event: FavoriteTaskEvent) {
if (event.isSucceeded) {
val status = event.status
val data = adapterData
if (status == null || data == null || data.isEmpty()) return
val adapter = adapter as ParcelableStatusesAdapter
val firstVisiblePosition = layoutManager!!.findFirstVisibleItemPosition()
val lastVisiblePosition = layoutManager!!.findLastVisibleItemPosition()
val startIndex = adapter.statusStartIndex
for (i in firstVisiblePosition..lastVisiblePosition) {
if (status.account_key == adapter.getAccountKey(i) && status.id == adapter.getStatusId(i)) {
if (data is MutableList) {
data[i - startIndex] = status
}
return
}
}
adapter.notifyDataSetChanged()
}
}
@Subscribe
fun notifyStatusDestroyed(event: StatusDestroyedEvent) {
}
@Subscribe
fun notifyStatusListChanged(event: StatusListChangedEvent) {
adapter!!.notifyDataSetChanged()
}
@Subscribe
fun notifyStatusRetweeted(event: StatusRetweetedEvent) {
}
@Subscribe
fun notifyAccountChanged(event: AccountChangedEvent) {
}
}
override val accountKeys: Array<UserKey>
get() {
val args = arguments
@ -197,7 +141,7 @@ abstract class CursorStatusesFragment : AbsStatusesFragment() {
reloadStatuses()
}
}
cr!!.registerContentObserver(Accounts.CONTENT_URI, true, contentObserver!!)
cr.registerContentObserver(Accounts.CONTENT_URI, true, contentObserver!!)
cr.registerContentObserver(Filters.CONTENT_URI, true, contentObserver!!)
updateRefreshState()
reloadStatuses()
@ -215,7 +159,7 @@ abstract class CursorStatusesFragment : AbsStatusesFragment() {
}
override fun onStop() {
contentResolver?.unregisterContentObserver(contentObserver!!)
contentResolver.unregisterContentObserver(contentObserver!!)
super.onStop()
}
@ -299,7 +243,6 @@ abstract class CursorStatusesFragment : AbsStatusesFragment() {
return DataStoreUtils.getNewestStatusIds(context, contentUri, accountKeys)
}
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
super.setUserVisibleHint(isVisibleToUser)
val context = context
@ -310,6 +253,7 @@ abstract class CursorStatusesFragment : AbsStatusesFragment() {
}
}
protected fun getOldestStatusIds(accountKeys: Array<UserKey>): Array<String>? {
val context = context ?: return null
return DataStoreUtils.getOldestStatusIds(context, contentUri, accountKeys)
@ -321,4 +265,60 @@ abstract class CursorStatusesFragment : AbsStatusesFragment() {
protected abstract fun updateRefreshState()
protected inner class CursorStatusesBusCallback {
@Subscribe
fun notifyGetStatusesTaskChanged(event: GetStatusesTaskEvent) {
if (event.uri != contentUri) return
refreshing = event.running
if (!event.running) {
setLoadMoreIndicatorPosition(ILoadMoreSupportAdapter.NONE)
refreshEnabled = true
showContentOrError()
}
}
@Subscribe
fun notifyFavoriteTask(event: FavoriteTaskEvent) {
if (event.isSucceeded) {
val status = event.status
val data = adapterData
if (status == null || data == null || data.isEmpty()) return
val adapter = adapter as ParcelableStatusesAdapter
val firstVisiblePosition = layoutManager!!.findFirstVisibleItemPosition()
val lastVisiblePosition = layoutManager!!.findLastVisibleItemPosition()
val startIndex = adapter.statusStartIndex
for (i in firstVisiblePosition..lastVisiblePosition) {
if (status.account_key == adapter.getAccountKey(i) && status.id == adapter.getStatusId(i)) {
if (data is MutableList) {
data[i - startIndex] = status
}
return
}
}
adapter.notifyDataSetChanged()
}
}
@Subscribe
fun notifyStatusDestroyed(event: StatusDestroyedEvent) {
}
@Subscribe
fun notifyStatusListChanged(event: StatusListChangedEvent) {
adapter!!.notifyDataSetChanged()
}
@Subscribe
fun notifyStatusRetweeted(event: StatusRetweetedEvent) {
}
@Subscribe
fun notifyAccountChanged(event: AccountChangedEvent) {
}
}
}

View File

@ -179,10 +179,6 @@ class DirectMessagesFragment : AbsContentListRecyclerViewFragment<MessageEntries
}
}
override fun onRefresh() {
triggerRefresh()
}
override fun scrollToStart(): Boolean {
val result = super.scrollToStart()
if (result) {

View File

@ -23,11 +23,10 @@ import android.text.TextUtils
import okhttp3.HttpUrl
import okhttp3.Interceptor
import okhttp3.Response
import org.attoparser.AttoParseException
import org.attoparser.markup.MarkupAttoParser
import org.attoparser.markup.html.AbstractStandardNonValidatingHtmlAttoHandler
import org.attoparser.markup.html.HtmlParsingConfiguration
import org.attoparser.markup.html.elements.IHtmlElement
import org.attoparser.ParseException
import org.attoparser.config.ParseConfiguration
import org.attoparser.simple.AbstractSimpleMarkupHandler
import org.attoparser.simple.SimpleMarkupParser
import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.twitter.TwitterOAuth
import org.mariotaku.restfu.RestAPIFactory
@ -139,28 +138,23 @@ class OAuthPasswordAuthenticator(
throw LoginVerificationException()
}
return data
} catch (e: AttoParseException) {
} catch (e: ParseException) {
throw LoginVerificationException("Login verification challenge failed", e)
} finally {
Utils.closeSilently(response)
}
}
@Throws(AttoParseException::class, IOException::class)
@Throws(ParseException::class, IOException::class)
private fun parseAuthorizeRequestData(response: HttpResponse, data: AuthorizeRequestData) {
val conf = HtmlParsingConfiguration()
val handler = object : AbstractStandardNonValidatingHtmlAttoHandler(conf) {
val handler = object : AbstractSimpleMarkupHandler() {
internal var isOAuthFormOpened: Boolean = false
override fun handleHtmlStandaloneElement(element: IHtmlElement?, minimized: Boolean,
elementName: String?, attributes: Map<String, String>?,
line: Int, col: Int) {
handleHtmlOpenElement(element, elementName, attributes, line, col)
handleHtmlCloseElement(element, elementName, line, col)
override fun handleStandaloneElement(elementName: String?, attributes: MutableMap<String, String>?, minimized: Boolean, line: Int, col: Int) {
handleOpenElement(elementName, attributes, line, col)
handleCloseElement(elementName, line, col)
}
override fun handleHtmlOpenElement(element: IHtmlElement?, elementName: String?,
attributes: Map<String, String>?, line: Int, col: Int) {
override fun handleOpenElement(elementName: String?, attributes: MutableMap<String, String>?, line: Int, col: Int) {
when (elementName) {
"form" -> {
if (attributes != null && "oauth_form" == attributes["id"]) {
@ -181,7 +175,7 @@ class OAuthPasswordAuthenticator(
}
}
override fun handleHtmlCloseElement(element: IHtmlElement?, elementName: String?, line: Int, col: Int) {
override fun handleCloseElement(elementName: String?, line: Int, col: Int) {
if ("form" == elementName) {
isOAuthFormOpened = false
}
@ -216,19 +210,18 @@ class OAuthPasswordAuthenticator(
authorizeResultBuilder.headers(requestHeaders)
authorizeResultBuilder.body(authorizationResultBody)
response = client.newCall(authorizeResultBuilder.build()).execute()
val conf = HtmlParsingConfiguration()
val handler = object : AbstractStandardNonValidatingHtmlAttoHandler(conf) {
val handler = object : AbstractSimpleMarkupHandler() {
internal var isOAuthPinDivOpened: Boolean = false
internal var isChallengeFormOpened: Boolean = false
override fun handleHtmlStandaloneElement(element: IHtmlElement?, minimized: Boolean,
elementName: String?, attributes: Map<String, String>?,
line: Int, col: Int) {
handleHtmlOpenElement(element, elementName, attributes, line, col)
handleHtmlCloseElement(element, elementName, line, col)
override fun handleStandaloneElement(elementName: String?,
attributes: MutableMap<String, String>?,
minimized: Boolean, line: Int, col: Int) {
handleOpenElement(elementName, attributes, line, col)
handleCloseElement(elementName, line, col)
}
override fun handleHtmlCloseElement(element: IHtmlElement?, elementName: String?, line: Int, col: Int) {
override fun handleCloseElement(elementName: String?, line: Int, col: Int) {
when (elementName) {
"div" -> {
isOAuthPinDivOpened = false
@ -239,8 +232,8 @@ class OAuthPasswordAuthenticator(
}
}
override fun handleHtmlOpenElement(element: IHtmlElement?, elementName: String?,
attributes: Map<String, String>?, line: Int, col: Int) {
override fun handleOpenElement(elementName: String?,
attributes: Map<String, String>?, line: Int, col: Int) {
when (elementName) {
"div" -> {
if (attributes != null && "oauth_pin" == attributes["id"]) {
@ -295,7 +288,7 @@ class OAuthPasswordAuthenticator(
}
}
@Throws(AttoParseException::class)
@Throws(ParseException::class)
override fun handleText(buffer: CharArray?, offset: Int, len: Int, line: Int, col: Int) {
if (isOAuthPinDivOpened) {
val s = String(buffer!!, offset, len)
@ -307,7 +300,7 @@ class OAuthPasswordAuthenticator(
}
PARSER.parse(SimpleBody.reader(response!!.body), handler)
return data
} catch (e: AttoParseException) {
} catch (e: ParseException) {
throw AuthenticationException("Malformed HTML", e)
} finally {
Utils.closeSilently(response)
@ -335,7 +328,7 @@ class OAuthPasswordAuthenticator(
throw AuthenticationException()
}
return data
} catch (e: AttoParseException) {
} catch (e: ParseException) {
throw AuthenticationException("Malformed HTML", e)
} finally {
Utils.closeSilently(response)
@ -458,22 +451,20 @@ class OAuthPasswordAuthenticator(
companion object {
private val PARSER = MarkupAttoParser()
private val PARSER = SimpleMarkupParser(ParseConfiguration.htmlConfiguration())
@Throws(AttoParseException::class, IOException::class)
@Throws(ParseException::class, IOException::class)
fun readOAuthPINFromHtml(reader: Reader, data: OAuthPinData) {
val conf = HtmlParsingConfiguration()
val handler = object : AbstractStandardNonValidatingHtmlAttoHandler(conf) {
val handler = object : AbstractSimpleMarkupHandler() {
internal var isOAuthPinDivOpened: Boolean = false
override fun handleHtmlStandaloneElement(element: IHtmlElement?, minimized: Boolean,
elementName: String?, attributes: Map<String, String>?,
line: Int, col: Int) {
handleHtmlOpenElement(element, elementName, attributes, line, col)
handleHtmlCloseElement(element, elementName, line, col)
override fun handleStandaloneElement(elementName: String?,
attributes: MutableMap<String, String>?,
minimized: Boolean, line: Int, col: Int) {
handleOpenElement(elementName, attributes, line, col)
handleCloseElement(elementName, line, col)
}
override fun handleHtmlOpenElement(element: IHtmlElement?, elementName: String?, attributes: Map<String, String>?, line: Int, col: Int) {
override fun handleOpenElement(elementName: String?, attributes: Map<String, String>?, line: Int, col: Int) {
when (elementName) {
"div" -> {
if (attributes != null && "oauth_pin" == attributes["id"]) {
@ -483,7 +474,7 @@ class OAuthPasswordAuthenticator(
}
}
override fun handleHtmlCloseElement(element: IHtmlElement?, elementName: String?, line: Int, col: Int) {
override fun handleCloseElement(elementName: String?, line: Int, col: Int) {
if ("div" == elementName) {
isOAuthPinDivOpened = false
}