Merge pull request #574 from TwidereProject/develop

Develop
This commit is contained in:
Mariotaku 2016-07-03 20:33:50 -05:00 committed by GitHub
commit 0eaecf8952
304 changed files with 3589 additions and 3591 deletions

View File

@ -7,10 +7,10 @@ android:
- tools
# The BuildTools version used by your project
- build-tools-23.0.3
- build-tools-24.0.0
# The SDK version used to compile your project
- android-23
- android-24
# Additional components
- extra-google-google_play_services
@ -24,7 +24,7 @@ android:
sudo: false
jdk:
- openjdk7
- oraclejdk8
env:
global:

View File

@ -25,8 +25,8 @@ Material Design ready and feature reach Twitter app for Android 4.0+
* Supports Twitter, Fanfou and GNU social
* Free, open source, NO ads, forever!
[![Get it on Google Play](http://www.android.com/images/brand/get_it_on_play_logo_large.png)](https://play.google.com/store/apps/details?id=org.mariotaku.twidere)
[![Get it on F-Droid](https://f-droid.org/wiki/images/0/06/F-Droid-button_get-it-on.png)](https://f-droid.org/repository/browse/?fdid=org.mariotaku.twidere)
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png" alt="Get it on Google Play" height="80">](https://play.google.com/store/apps/details?id=org.mariotaku.twidere)
[<img src="https://f-droid.org/badge/get-it-on.png" alt="Get it on F-Droid" height="80">](https://f-droid.org/repository/browse/?fdid=org.mariotaku.twidere)
---

View File

@ -2,19 +2,21 @@ apply plugin: 'com.github.ben-manes.versions'
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.0.2'
repositories {
jcenter()
maven { url 'https://plugins.gradle.org/m2/' }
}
dependencies {
classpath 'com.github.ben-manes:gradle-versions-plugin:0.12.0'
classpath 'com.android.tools.build:gradle:2.1.0'
classpath 'com.google.gms:google-services:2.1.0'
classpath 'com.android.tools.build:gradle:2.1.2'
classpath 'com.google.gms:google-services:3.0.0'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
classpath('fr.avianey.androidsvgdrawable:gradle-plugin:3.0.0') {
// should be excluded to avoid conflict
exclude group: 'xerces'
}
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
@ -34,8 +36,8 @@ subprojects {
if (project.hasProperty('android')) {
android {
compileSdkVersion 23
buildToolsVersion '23.0.3'
compileSdkVersion 24
buildToolsVersion '24.0.0'
lintOptions {
abortOnError false

View File

@ -23,7 +23,7 @@ apply plugin: 'com.neenbedankt.android-apt'
android {
defaultConfig {
minSdkVersion 14
targetSdkVersion 23
targetSdkVersion 24
versionCode 1
versionName "3.0"
}
@ -39,12 +39,13 @@ dependencies {
apt 'com.bluelinelabs:logansquare-compiler:1.3.7'
apt 'com.hannesdorfmann.parcelableplease:processor:1.0.2'
apt 'com.github.mariotaku.ObjectCursor:processor:0.9.7'
compile 'com.android.support:support-annotations:23.4.0'
compile 'com.android.support:support-annotations:24.0.0'
compile 'com.bluelinelabs:logansquare:1.3.7'
compile 'com.github.mariotaku.RestFu:library:0.9.27'
compile 'com.github.mariotaku.RestFu:library:0.9.30'
compile 'com.github.mariotaku.RestFu:oauth:0.9.30'
compile 'com.hannesdorfmann.parcelableplease:annotation:1.0.2'
compile 'com.github.mariotaku.ObjectCursor:core:0.9.7'
compile 'com.github.mariotaku.CommonsLibrary:objectcursor:0.9.4'
compile 'com.github.mariotaku.CommonsLibrary:logansquare:0.9.4'
compile 'com.github.mariotaku.CommonsLibrary:objectcursor:0.9.8'
compile 'com.github.mariotaku.CommonsLibrary:logansquare:0.9.8'
compile fileTree(dir: 'libs', include: ['*.jar'])
}

View File

@ -20,7 +20,7 @@ package org.mariotaku.twidere;
interface IMediaUploader {
String upload(String statusJson, String mediaJson);
String upload(String statusJson, String currentAccountKey, String mediaJson);
boolean callback(String resultJson, String statusJson);

View File

@ -88,6 +88,10 @@ public class MicroBlogException extends Exception implements TwitterResponse, Ht
return errors;
}
public void setErrors(ErrorInfo[] errors) {
this.errors = errors;
}
/**
* Tests if the exception is caused by rate limitation exceed
*

View File

@ -1,6 +1,7 @@
package org.mariotaku.microblog.library.statusnet.api;
import org.mariotaku.restfu.annotation.method.GET;
import org.mariotaku.restfu.annotation.method.POST;
import org.mariotaku.restfu.annotation.param.Path;
import org.mariotaku.restfu.annotation.param.Query;
import org.mariotaku.microblog.library.statusnet.model.StatusNetConfig;
@ -19,4 +20,5 @@ public interface StatusNetResources {
@GET("/statusnet/conversation/{id}.json")
ResponseList<Status> getStatusNetConversation(@Path("id") String statusId, @Query Paging paging) throws MicroBlogException;
}

View File

@ -20,13 +20,13 @@
package org.mariotaku.microblog.library.twitter;
import org.mariotaku.microblog.library.MicroBlogException;
import org.mariotaku.restfu.annotation.method.POST;
import org.mariotaku.restfu.annotation.param.Extra;
import org.mariotaku.restfu.annotation.param.KeyValue;
import org.mariotaku.restfu.annotation.param.Param;
import org.mariotaku.restfu.annotation.param.Params;
import org.mariotaku.microblog.library.MicroBlogException;
import org.mariotaku.microblog.library.twitter.auth.OAuthToken;
import org.mariotaku.restfu.oauth.OAuthToken;
/**
* Created by mariotaku on 15/2/4.

View File

@ -19,6 +19,11 @@
package org.mariotaku.microblog.library.twitter;
import org.mariotaku.microblog.library.MicroBlogException;
import org.mariotaku.microblog.library.twitter.model.MediaUploadResponse;
import org.mariotaku.microblog.library.twitter.model.NewMediaMetadata;
import org.mariotaku.microblog.library.twitter.model.ResponseCode;
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;
@ -26,38 +31,36 @@ import org.mariotaku.restfu.annotation.param.Params;
import org.mariotaku.restfu.annotation.param.Raw;
import org.mariotaku.restfu.http.BodyType;
import org.mariotaku.restfu.http.mime.Body;
import org.mariotaku.microblog.library.MicroBlogException;
import org.mariotaku.microblog.library.twitter.model.MediaUploadResponse;
import org.mariotaku.microblog.library.twitter.model.NewMediaMetadata;
import org.mariotaku.microblog.library.twitter.model.ResponseCode;
import java.io.File;
public interface TwitterUpload {
@POST("/media/upload.json")
@BodyType(BodyType.MULTIPART)
MediaUploadResponse uploadMedia(@Param("media") File file) throws MicroBlogException;
@POST("/media/upload.json")
@BodyType(BodyType.MULTIPART)
MediaUploadResponse uploadMedia(@Param("media") Body data) throws MicroBlogException;
MediaUploadResponse uploadMedia(@Param("media") Body data,
@Param(value = "additional_owners", arrayDelimiter = ',')
String[] additionalOwners) throws MicroBlogException;
@POST("/media/upload.json")
@Params(@KeyValue(key = "command", value = "INIT"))
MediaUploadResponse initUploadMedia(@Param("media_type") String mediaType,
@Param("total_bytes") long totalBytes) throws MicroBlogException;
@Param("total_bytes") long totalBytes,
@Param(value = "additional_owners", arrayDelimiter = ',')
String[] additionalOwners) throws MicroBlogException;
@POST("/media/upload.json")
@Params(@KeyValue(key = "command", value = "APPEND"))
ResponseCode initUploadMedia(@Param("media_id") long mediaId,
@Param("segment_index") int segmentIndex,
@Param("media") Body media) throws MicroBlogException;
ResponseCode appendUploadMedia(@Param("media_id") String mediaId,
@Param("segment_index") int segmentIndex,
@Param("media") Body media) throws MicroBlogException;
@POST("/media/upload.json")
@Params(@KeyValue(key = "command", value = "FINALIZE"))
MediaUploadResponse initUploadMedia(@Param("media_id") long mediaId) throws MicroBlogException;
MediaUploadResponse finalizeUploadMedia(@Param("media_id") String mediaId) throws MicroBlogException;
@GET("/media/upload.json")
@Params(@KeyValue(key = "command", value = "STATUS"))
MediaUploadResponse getUploadMediaStatus(@Param("media_id") String mediaId) throws MicroBlogException;
@POST("/media/metadata/create.json")
ResponseCode createMetadata(@Raw NewMediaMetadata metadata) throws MicroBlogException;

View File

@ -19,27 +19,19 @@
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.microblog.library.MicroBlogException;
import org.mariotaku.microblog.library.twitter.model.Paging;
import org.mariotaku.microblog.library.twitter.model.ResponseList;
import org.mariotaku.microblog.library.twitter.model.Status;
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.Param;
import org.mariotaku.restfu.annotation.param.Queries;
import org.mariotaku.restfu.annotation.param.Query;
@SuppressWarnings("RedundantThrows")
@Queries({@KeyValue(key = "include_my_retweet", valueKey = "include_my_retweet"),
@KeyValue(key = "include_rts", valueKey = "include_entities"),
@KeyValue(key = "include_entities", valueKey = "include_entities"),
@KeyValue(key = "include_cards", valueKey = "include_cards"),
@KeyValue(key = "cards_platform", valueKey = "cards_platform"),
@KeyValue(key = "include_reply_count", valueKey = "include_reply_count"),
@KeyValue(key = "include_descendent_reply_count", valueKey = "include_descendent_reply_count"),
@KeyValue(key = "include_ext_alt_text", valueKey = "include_ext_alt_text")
})
@Queries(template = StatusAnnotationTemplate.class)
public interface FavoritesResources {
@POST("/favorites/create.json")
@ -52,8 +44,8 @@ public interface FavoritesResources {
ResponseList<Status> getFavorites() throws MicroBlogException;
@GET("/favorites/list.json")
ResponseList<Status> getFavorites(@Query("user_id") String userId, @Query({"since_id", "max_id", "count"}) Paging paging) throws MicroBlogException;
ResponseList<Status> getFavorites(@Query("user_id") String userId, @Query Paging paging) throws MicroBlogException;
@GET("/favorites/list.json")
ResponseList<Status> getFavoritesByScreenName(@Query("screen_name") String screenName, @Query({"since_id", "max_id", "count"}) Paging paging) throws MicroBlogException;
ResponseList<Status> getFavoritesByScreenName(@Query("screen_name") String screenName, @Query Paging paging) throws MicroBlogException;
}

View File

@ -19,6 +19,7 @@
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;
@ -116,39 +117,15 @@ public interface ListResources {
ResponseList<UserList> getUserListsByScreenName(@Query("screen_name") String screenName, @Query("reverse") boolean reverse) throws MicroBlogException;
@GET("/lists/statuses.json")
@Queries({@KeyValue(key = "include_my_retweet", valueKey = "include_my_retweet"),
@KeyValue(key = "include_rts", valueKey = "include_entities"),
@KeyValue(key = "include_entities", valueKey = "include_entities"),
@KeyValue(key = "include_cards", valueKey = "include_cards"),
@KeyValue(key = "cards_platform", valueKey = "cards_platform"),
@KeyValue(key = "include_reply_count", valueKey = "include_reply_count"),
@KeyValue(key = "include_descendent_reply_count", valueKey = "include_descendent_reply_count"),
@KeyValue(key = "include_ext_alt_text", valueKey = "include_ext_alt_text")
})
@Queries(template = StatusAnnotationTemplate.class)
ResponseList<Status> getUserListStatuses(@Query("list_id") String listId, @Query Paging paging) throws MicroBlogException;
@GET("/lists/statuses.json")
@Queries({@KeyValue(key = "include_my_retweet", valueKey = "include_my_retweet"),
@KeyValue(key = "include_rts", valueKey = "include_entities"),
@KeyValue(key = "include_entities", valueKey = "include_entities"),
@KeyValue(key = "include_cards", valueKey = "include_cards"),
@KeyValue(key = "cards_platform", valueKey = "cards_platform"),
@KeyValue(key = "include_reply_count", valueKey = "include_reply_count"),
@KeyValue(key = "include_descendent_reply_count", valueKey = "include_descendent_reply_count"),
@KeyValue(key = "include_ext_alt_text", valueKey = "include_ext_alt_text")
})
@Queries(template = StatusAnnotationTemplate.class)
ResponseList<Status> getUserListStatuses(@Query("slug") String slug, @Query("owner_id") long ownerId, @Query Paging paging) throws MicroBlogException;
@GET("/lists/statuses.json")
@Queries({@KeyValue(key = "include_my_retweet", valueKey = "include_my_retweet"),
@KeyValue(key = "include_rts", valueKey = "include_entities"),
@KeyValue(key = "include_entities", valueKey = "include_entities"),
@KeyValue(key = "include_cards", valueKey = "include_cards"),
@KeyValue(key = "cards_platform", valueKey = "cards_platform"),
@KeyValue(key = "include_reply_count", valueKey = "include_reply_count"),
@KeyValue(key = "include_descendent_reply_count", valueKey = "include_descendent_reply_count"),
@KeyValue(key = "include_ext_alt_text", valueKey = "include_ext_alt_text")
})
@Queries(template = StatusAnnotationTemplate.class)
ResponseList<Status> getUserListStatuses(@Query("slug") String slug, @Query("owner_screen_name") String ownerScreenName, @Query Paging paging)
throws MicroBlogException;

View File

@ -19,6 +19,7 @@
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;
@ -33,15 +34,7 @@ import org.mariotaku.microblog.library.twitter.model.Paging;
import org.mariotaku.microblog.library.twitter.model.ResponseList;
@SuppressWarnings("RedundantThrows")
@Queries({@KeyValue(key = "include_my_retweet", valueKey = "include_my_retweet"),
@KeyValue(key = "include_rts", valueKey = "include_entities"),
@KeyValue(key = "include_entities", valueKey = "include_entities"),
@KeyValue(key = "include_cards", valueKey = "include_cards"),
@KeyValue(key = "cards_platform", valueKey = "cards_platform"),
@KeyValue(key = "include_reply_count", valueKey = "include_reply_count"),
@KeyValue(key = "include_descendent_reply_count", valueKey = "include_descendent_reply_count"),
@KeyValue(key = "model_version", valueKey = "model_version"),
@KeyValue(key = "skip_aggregation", valueKey = "skip_aggregation")})
@Queries(template = StatusAnnotationTemplate.class)
public interface PrivateActivityResources extends PrivateResources {
@GET("/activity/about_me.json")

View File

@ -19,6 +19,7 @@
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.param.KeyValue;
import org.mariotaku.restfu.annotation.param.Queries;
@ -29,15 +30,7 @@ import org.mariotaku.microblog.library.twitter.model.ResponseList;
import org.mariotaku.microblog.library.twitter.model.Status;
@SuppressWarnings("RedundantThrows")
@Queries({@KeyValue(key = "include_my_retweet", valueKey = "include_my_retweet"),
@KeyValue(key = "include_rts", valueKey = "include_entities"),
@KeyValue(key = "include_entities", valueKey = "include_entities"),
@KeyValue(key = "include_cards", valueKey = "include_cards"),
@KeyValue(key = "cards_platform", valueKey = "cards_platform"),
@KeyValue(key = "include_reply_count", valueKey = "include_reply_count"),
@KeyValue(key = "include_descendent_reply_count", valueKey = "include_descendent_reply_count"),
@KeyValue(key = "include_ext_alt_text", valueKey = "include_ext_alt_text")
})
@Queries(template = StatusAnnotationTemplate.class)
public interface PrivateTimelineResources extends PrivateResources {
@GET("/statuses/media_timeline.json")

View File

@ -19,6 +19,7 @@
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.param.KeyValue;
import org.mariotaku.restfu.annotation.param.Path;
@ -32,15 +33,7 @@ import org.mariotaku.microblog.library.twitter.model.StatusActivitySummary;
import org.mariotaku.microblog.library.twitter.model.TranslationResult;
@SuppressWarnings("RedundantThrows")
@Queries({@KeyValue(key = "include_my_retweet", valueKey = "include_my_retweet"),
@KeyValue(key = "include_rts", valueKey = "include_entities"),
@KeyValue(key = "include_entities", valueKey = "include_entities"),
@KeyValue(key = "include_cards", valueKey = "include_cards"),
@KeyValue(key = "cards_platform", valueKey = "cards_platform"),
@KeyValue(key = "include_reply_count", valueKey = "include_reply_count"),
@KeyValue(key = "include_descendent_reply_count", valueKey = "include_descendent_reply_count"),
@KeyValue(key = "include_ext_alt_text", valueKey = "include_ext_alt_text")
})
@Queries(template = StatusAnnotationTemplate.class)
public interface PrivateTweetResources extends PrivateResources {
@GET("/statuses/{id}/activity/summary.json")

View File

@ -19,22 +19,16 @@
package org.mariotaku.microblog.library.twitter.api;
import org.mariotaku.restfu.annotation.method.GET;
import org.mariotaku.restfu.annotation.param.KeyValue;
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.QueryResult;
import org.mariotaku.microblog.library.twitter.model.SearchQuery;
import org.mariotaku.microblog.library.twitter.template.StatusAnnotationTemplate;
import org.mariotaku.restfu.annotation.method.GET;
import org.mariotaku.restfu.annotation.param.Queries;
import org.mariotaku.restfu.annotation.param.Query;
@SuppressWarnings("RedundantThrows")
@Queries({@KeyValue(key = "include_my_retweet", valueKey = "include_my_retweet"),
@KeyValue(key = "include_rts", valueKey = "include_entities"),
@KeyValue(key = "include_entities", valueKey = "include_entities"),
@KeyValue(key = "include_cards", valueKey = "include_cards"),
@KeyValue(key = "cards_platform", valueKey = "cards_platform"),
@KeyValue(key = "include_reply_count", valueKey = "include_reply_count"),
@KeyValue(key = "include_descendent_reply_count", valueKey = "include_descendent_reply_count")})
@Queries(template = StatusAnnotationTemplate.class)
public interface SearchResource {
@GET("/search/tweets.json")
QueryResult search(@Query SearchQuery query) throws MicroBlogException;

View File

@ -20,25 +20,16 @@
package org.mariotaku.microblog.library.twitter.api;
import org.mariotaku.restfu.annotation.method.GET;
import org.mariotaku.restfu.annotation.param.KeyValue;
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.Paging;
import org.mariotaku.microblog.library.twitter.model.ResponseList;
import org.mariotaku.microblog.library.twitter.model.Status;
import org.mariotaku.microblog.library.twitter.template.StatusAnnotationTemplate;
import org.mariotaku.restfu.annotation.method.GET;
import org.mariotaku.restfu.annotation.param.Queries;
import org.mariotaku.restfu.annotation.param.Query;
@SuppressWarnings("RedundantThrows")
@Queries({@KeyValue(key = "include_my_retweet", valueKey = "include_my_retweet"),
@KeyValue(key = "include_rts", valueKey = "include_entities"),
@KeyValue(key = "include_entities", valueKey = "include_entities"),
@KeyValue(key = "include_cards", valueKey = "include_cards"),
@KeyValue(key = "cards_platform", valueKey = "cards_platform"),
@KeyValue(key = "include_reply_count", valueKey = "include_reply_count"),
@KeyValue(key = "include_descendent_reply_count", valueKey = "include_descendent_reply_count"),
@KeyValue(key = "include_ext_alt_text", valueKey = "include_ext_alt_text")
})
@Queries(template = StatusAnnotationTemplate.class)
public interface TimelineResources {
@GET("/statuses/home_timeline.json")

View File

@ -3,6 +3,7 @@ package org.mariotaku.microblog.library.twitter.auth;
import android.util.Base64;
import org.mariotaku.restfu.http.HeaderValue;
import org.mariotaku.restfu.oauth.OAuthToken;
/**
* Created by mariotaku on 16/1/4.

View File

@ -1,229 +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.microblog.library.twitter.auth;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Base64;
import org.mariotaku.restfu.Pair;
import org.mariotaku.restfu.RestFuUtils;
import org.mariotaku.restfu.RestRequest;
import org.mariotaku.restfu.http.Authorization;
import org.mariotaku.restfu.http.BodyType;
import org.mariotaku.restfu.http.Endpoint;
import org.mariotaku.restfu.http.MultiValueMap;
import org.mariotaku.restfu.http.mime.Body;
import org.mariotaku.restfu.http.mime.StringBody;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
/**
* Created by mariotaku on 15/2/4.
*/
public class OAuthAuthorization implements Authorization, OAuthSupport {
private static final String DEFAULT_ENCODING = "UTF-8";
private static final String OAUTH_SIGNATURE_METHOD = "HMAC-SHA1";
private static final String OAUTH_VERSION = "1.0";
private final String consumerKey, consumerSecret;
private final OAuthToken oauthToken;
SecureRandom secureRandom = new SecureRandom();
public OAuthAuthorization(String consumerKey, String consumerSecret) {
this(consumerKey, consumerSecret, null);
}
public OAuthAuthorization(String consumerKey, String consumerSecret, OAuthToken oauthToken) {
this.consumerKey = consumerKey;
this.consumerSecret = consumerSecret;
this.oauthToken = oauthToken;
}
@Override
public String getConsumerKey() {
return consumerKey;
}
@Override
public String getConsumerSecret() {
return consumerSecret;
}
public OAuthToken getOauthToken() {
return oauthToken;
}
private String generateOAuthSignature(String method, String url,
String oauthNonce, long timestamp,
String oauthToken, String oauthTokenSecret,
@Nullable MultiValueMap<String> queries,
@Nullable MultiValueMap<Body> params,
@NonNull String bodyType) {
final List<String> encodeParams = new ArrayList<>();
encodeParams.add(encodeParameter("oauth_consumer_key", consumerKey));
encodeParams.add(encodeParameter("oauth_nonce", oauthNonce));
encodeParams.add(encodeParameter("oauth_signature_method", OAUTH_SIGNATURE_METHOD));
encodeParams.add(encodeParameter("oauth_timestamp", String.valueOf(timestamp)));
encodeParams.add(encodeParameter("oauth_version", OAUTH_VERSION));
if (oauthToken != null) {
encodeParams.add(encodeParameter("oauth_token", oauthToken));
}
if (queries != null) {
for (Pair<String, String> query : queries.toList()) {
encodeParams.add(encodeParameter(query.first, query.second));
}
}
if (params != null && BodyType.FORM.equals(bodyType)) {
for (Pair<String, Body> form : params.toList()) {
encodeParams.add(encodeParameter(form.first, ((StringBody) form.second).value()));
}
}
Collections.sort(encodeParams);
final StringBuilder paramBuilder = new StringBuilder();
for (int i = 0, j = encodeParams.size(); i < j; i++) {
if (i != 0) {
paramBuilder.append('&');
}
paramBuilder.append(encodeParams.get(i));
}
final String signingKey;
if (oauthTokenSecret != null) {
signingKey = encode(consumerSecret) + '&' + encode(oauthTokenSecret);
} else {
signingKey = encode(consumerSecret) + '&';
}
try {
final Mac mac = Mac.getInstance("HmacSHA1");
SecretKeySpec secret = new SecretKeySpec(signingKey.getBytes(), mac.getAlgorithm());
mac.init(secret);
String urlNoQuery = url.indexOf('?') != -1 ? url.substring(0, url.indexOf('?')) : url;
final String baseString = encode(method) + '&' + encode(urlNoQuery) + '&' + encode(paramBuilder.toString());
final byte[] signature = mac.doFinal(baseString.getBytes(DEFAULT_ENCODING));
return Base64.encodeToString(signature, Base64.NO_WRAP);
} catch (NoSuchAlgorithmException e) {
throw new UnsupportedOperationException(e);
} catch (InvalidKeyException | UnsupportedEncodingException e) {
throw new AssertionError(e);
}
}
@Override
public String getHeader(Endpoint endpoint, RestRequest request) {
if (!(endpoint instanceof OAuthEndpoint))
throw new IllegalArgumentException("OAuthEndpoint required");
final Map<String, Object> extras = request.getExtras();
final String oauthToken, oauthTokenSecret;
if (this.oauthToken != null) {
oauthToken = this.oauthToken.getOauthToken();
oauthTokenSecret = this.oauthToken.getOauthTokenSecret();
} else {
oauthToken = (String) extras.get("oauth_token");
oauthTokenSecret = (String) extras.get("oauth_token_secret");
}
final OAuthEndpoint oauthEndpoint = (OAuthEndpoint) endpoint;
final String method = request.getMethod();
final String url = Endpoint.constructUrl(oauthEndpoint.getSignUrl(), request);
final MultiValueMap<String> queries = request.getQueries();
final MultiValueMap<Body> params = request.getParams();
final List<Pair<String, String>> encodeParams = generateOAuthParams(oauthToken, oauthTokenSecret,
method, url, queries, params, request.getBodyType());
final StringBuilder headerBuilder = new StringBuilder();
headerBuilder.append("OAuth ");
for (int i = 0, j = encodeParams.size(); i < j; i++) {
if (i != 0) {
headerBuilder.append(", ");
}
final Pair<String, String> keyValuePair = encodeParams.get(i);
headerBuilder.append(keyValuePair.first);
headerBuilder.append("=\"");
headerBuilder.append(keyValuePair.second);
headerBuilder.append('\"');
}
return headerBuilder.toString();
}
public List<Pair<String, String>> generateOAuthParams(String oauthToken,
String oauthTokenSecret, String method,
String url, MultiValueMap<String> queries,
MultiValueMap<Body> params,
String bodyType) {
final String oauthNonce = generateOAuthNonce();
final long timestamp = System.currentTimeMillis() / 1000;
final String oauthSignature = generateOAuthSignature(method, url, oauthNonce, timestamp, oauthToken,
oauthTokenSecret, queries, params, bodyType);
final List<Pair<String, String>> encodeParams = new ArrayList<>();
encodeParams.add(Pair.create("oauth_consumer_key", consumerKey));
encodeParams.add(Pair.create("oauth_nonce", oauthNonce));
encodeParams.add(Pair.create("oauth_signature", encode(oauthSignature)));
encodeParams.add(Pair.create("oauth_signature_method", OAUTH_SIGNATURE_METHOD));
encodeParams.add(Pair.create("oauth_timestamp", String.valueOf(timestamp)));
encodeParams.add(Pair.create("oauth_version", OAUTH_VERSION));
if (oauthToken != null) {
encodeParams.add(Pair.create("oauth_token", oauthToken));
}
Collections.sort(encodeParams, new Comparator<Pair<String, String>>() {
@Override
public int compare(Pair<String, String> lhs, Pair<String, String> rhs) {
return lhs.first.compareTo(rhs.first);
}
});
return encodeParams;
}
@Override
public boolean hasAuthorization() {
return true;
}
private String encodeParameter(String key, String value) {
return encode(key) + '=' + encode(value);
}
private static String encode(final String value) {
return RestFuUtils.encode(value, DEFAULT_ENCODING);
}
private static final char[] VALID_NONCE_CHARACTERS = {'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F',
'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z'};
private String generateOAuthNonce() {
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < 32; i++) {
sb.append(VALID_NONCE_CHARACTERS[secureRandom.nextInt(VALID_NONCE_CHARACTERS.length)]);
}
return sb.toString();
}
}

View File

@ -1,42 +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.microblog.library.twitter.auth;
import org.mariotaku.restfu.http.Endpoint;
/**
* Created by mariotaku on 15/2/6.
*/
public class OAuthEndpoint extends Endpoint {
private final String signUrl;
public OAuthEndpoint(String url) {
this(url, url);
}
public OAuthEndpoint(String url, String signUrl) {
super(url);
this.signUrl = signUrl != null ? signUrl : url;
}
public String getSignUrl() {
return signUrl;
}
}

View File

@ -1,29 +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.microblog.library.twitter.auth;
/**
* Created by mariotaku on 15/5/7.
*/
public interface OAuthSupport {
String getConsumerKey();
String getConsumerSecret();
}

View File

@ -1,149 +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.microblog.library.twitter.auth;
import org.mariotaku.restfu.RestConverter;
import org.mariotaku.restfu.RestFuUtils;
import org.mariotaku.restfu.http.ContentType;
import org.mariotaku.restfu.http.HttpResponse;
import org.mariotaku.restfu.http.ValueMap;
import org.mariotaku.restfu.http.mime.Body;
import org.mariotaku.microblog.library.MicroBlogException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.text.ParseException;
/**
* Created by mariotaku on 15/2/4.
*/
public class OAuthToken implements ValueMap {
private String screenName;
private String userId;
private String oauthToken, oauthTokenSecret;
public String getScreenName() {
return screenName;
}
public String getUserId() {
return userId;
}
public String getOauthTokenSecret() {
return oauthTokenSecret;
}
public String getOauthToken() {
return oauthToken;
}
public OAuthToken(String oauthToken, String oauthTokenSecret) {
this.oauthToken = oauthToken;
this.oauthTokenSecret = oauthTokenSecret;
}
public OAuthToken(String body, Charset charset) throws ParseException {
RestFuUtils.parseQuery(body, charset.name(), new RestFuUtils.KeyValueConsumer() {
@Override
public void consume(String key, String value) {
switch (key) {
case "oauth_token": {
oauthToken = value;
break;
}
case "oauth_token_secret": {
oauthTokenSecret = value;
break;
}
case "user_id": {
userId = value;
break;
}
case "screen_name": {
screenName = value;
break;
}
}
}
});
if (oauthToken == null || oauthTokenSecret == null) {
throw new ParseException("Unable to parse request token", -1);
}
}
@Override
public boolean has(String key) {
return "oauth_token".equals(key) || "oauth_token_secret".equals(key);
}
@Override
public String toString() {
return "OAuthToken{" +
"screenName='" + screenName + '\'' +
", userId=" + userId +
", oauthToken='" + oauthToken + '\'' +
", oauthTokenSecret='" + oauthTokenSecret + '\'' +
'}';
}
@Override
public String get(String key) {
if ("oauth_token".equals(key)) {
return oauthToken;
} else if ("oauth_token_secret".equals(key)) {
return oauthTokenSecret;
}
return null;
}
@Override
public String[] keys() {
return new String[]{"oauth_token", "oauth_token_secret"};
}
public static class ResponseConverter implements RestConverter<HttpResponse, OAuthToken, MicroBlogException> {
@Override
public OAuthToken convert(HttpResponse response) throws IOException, ConvertException {
final Body body = response.getBody();
try {
final ContentType contentType = body.contentType();
final ByteArrayOutputStream os = new ByteArrayOutputStream();
body.writeTo(os);
Charset charset = contentType != null ? contentType.getCharset() : null;
if (charset == null) {
charset = Charset.defaultCharset();
}
try {
return new OAuthToken(os.toString(charset.name()), charset);
} catch (ParseException e) {
throw new ConvertException(e);
}
} finally {
RestFuUtils.closeSilently(body);
}
}
}
}

View File

@ -33,7 +33,6 @@ import com.bluelinelabs.logansquare.annotation.OnJsonParseComplete;
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
import org.mariotaku.commons.logansquare.JsonStringConverter;
import org.mariotaku.microblog.library.annotation.NoObfuscate;
import org.mariotaku.microblog.library.twitter.util.TwitterDateConverter;
import java.io.IOException;
@ -247,25 +246,28 @@ public class Activity extends TwitterResponseObject implements TwitterResponse,
}
}
public static Activity fromMention(String twitterId, Status status) {
public static Activity fromMention(String accountId, Status status) {
final Activity activity = new Activity();
activity.maxPosition = activity.minPosition = status.getId();
activity.maxSortPosition = activity.minSortPosition = status.getSortId();
activity.createdAt = status.getCreatedAt();
if (TextUtils.equals(status.getInReplyToUserId(), twitterId)) {
if (TextUtils.equals(status.getInReplyToUserId(), accountId)) {
activity.action = Action.REPLY;
activity.targetStatuses = new Status[]{status};
//TODO set target statuses (in reply to status)
activity.targetObjectStatuses = new Status[0];
} else if (status.quotedStatus != null && TextUtils.equals(status.quotedStatus.user.getId(),
accountId)) {
activity.action = Action.QUOTE;
activity.targetStatuses = new Status[]{status};
activity.targetObjectStatuses = new Status[0];
} else {
activity.action = Action.MENTION;
activity.targetUsers = new User[0];
activity.targetObjectStatuses = new Status[]{status};
// TODO set target users (mentioned users)
activity.targetUsers = null;
}
activity.sourcesSize = 1;
activity.sources = new User[]{status.getUser()};

View File

@ -37,6 +37,11 @@ public class ErrorInfo {
@JsonField(name = "code")
int code;
/**
* Field for https://dev.twitter.com/rest/reference/get/media/upload-status
*/
@JsonField(name = "name")
String name;
@JsonField(name = "message")
String message;
@ -44,6 +49,10 @@ public class ErrorInfo {
return code;
}
public String getName() {
return name;
}
public String getMessage() {
return message;
}

View File

@ -19,6 +19,8 @@
package org.mariotaku.microblog.library.twitter.model;
import android.support.annotation.StringDef;
import com.bluelinelabs.logansquare.annotation.JsonField;
import com.bluelinelabs.logansquare.annotation.JsonObject;
@ -36,6 +38,8 @@ public class MediaUploadResponse extends TwitterResponseObject implements Twitte
Image image;
@JsonField(name = "video")
Video video;
@JsonField(name = "processing_info")
ProcessingInfo processingInfo;
public String getId() {
return mediaId;
@ -53,6 +57,21 @@ public class MediaUploadResponse extends TwitterResponseObject implements Twitte
return video;
}
public ProcessingInfo getProcessingInfo() {
return processingInfo;
}
@Override
public String toString() {
return "MediaUploadResponse{" +
"mediaId='" + mediaId + '\'' +
", size=" + size +
", image=" + image +
", video=" + video +
", processingInfo=" + processingInfo +
"} " + super.toString();
}
@JsonObject
public static class Video {
@JsonField(name = "video_type")
@ -61,6 +80,13 @@ public class MediaUploadResponse extends TwitterResponseObject implements Twitte
public String getVideoType() {
return videoType;
}
@Override
public String toString() {
return "Video{" +
"videoType='" + videoType + '\'' +
'}';
}
}
@JsonObject
@ -84,5 +110,62 @@ public class MediaUploadResponse extends TwitterResponseObject implements Twitte
public int getWidth() {
return width;
}
@Override
public String toString() {
return "Image{" +
"width=" + width +
", height=" + height +
", imageType='" + imageType + '\'' +
'}';
}
}
@JsonObject
public static class ProcessingInfo {
@JsonField(name = "state")
@State
String state;
@JsonField(name = "check_after_secs")
long checkAfterSecs;
@JsonField(name = "progress_percent")
int progressPercent;
@JsonField(name = "error")
ErrorInfo error;
@State
public String getState() {
return state;
}
public long getCheckAfterSecs() {
return checkAfterSecs;
}
public int getProgressPercent() {
return progressPercent;
}
public ErrorInfo getError() {
return error;
}
@Override
public String toString() {
return "ProcessingInfo{" +
"state='" + state + '\'' +
", checkAfterSecs=" + checkAfterSecs +
'}';
}
@StringDef({State.PENDING, State.IN_PROGRESS, State.FAILED, State.SUCCEEDED})
public @interface State {
String PENDING = "pending";
String IN_PROGRESS = "in_progress";
String FAILED = "failed";
String SUCCEEDED = "succeeded";
}
}
}

View File

@ -61,6 +61,12 @@ public class Status extends TwitterResponseObject implements Comparable<Status>,
@JsonField(name = "text")
String text;
/**
* https://dev.twitter.com/overview/api/upcoming-changes-to-tweets
*/
@JsonField(name = "full_text")
String fullText;
@JsonField(name = "statusnet_html")
String statusnetHtml;
@ -129,9 +135,18 @@ public class Status extends TwitterResponseObject implements Comparable<Status>,
@JsonField(name = "quoted_status")
Status quotedStatus;
@JsonField(name = "is_quote_status")
boolean isQuoteStatus;
@JsonField(name = "quoted_status_id_str")
String quotedStatusId;
@JsonField(name = "repost_status")
Status repostStatus;
@JsonField(name = "repost_status_id")
String repostStatusId;
@JsonField(name = "card")
CardEntity card;
@ -175,6 +190,9 @@ public class Status extends TwitterResponseObject implements Comparable<Status>,
@JsonField(name = "location")
String location;
@JsonField(name = "display_text_range")
int[] displayTextRange;
@ParcelableNoThanks
private transient long sortId = -1;
@ -204,13 +222,22 @@ public class Status extends TwitterResponseObject implements Comparable<Status>,
return truncated;
}
public String getText() {
return text;
}
public String getFullText() {
return fullText;
}
public String getExtendedText() {
if (fullText != null) return fullText;
return text;
}
public String getHtmlText() {
if (statusnetHtml != null) return statusnetHtml;
if (fullText != null) return fullText;
return text;
}
@ -256,12 +283,6 @@ public class Status extends TwitterResponseObject implements Comparable<Status>,
return retweetedStatus != null;
}
public boolean isQuote() {
return quotedStatus != null;
}
public boolean isRetweetedByMe() {
return currentUserRetweet != null;
}
@ -414,6 +435,18 @@ public class Status extends TwitterResponseObject implements Comparable<Status>,
return location;
}
public int[] getDisplayTextRange() {
return displayTextRange;
}
public boolean isQuoteStatus() {
return isQuoteStatus;
}
public String getQuotedStatusId() {
return quotedStatusId;
}
@Override
public int compareTo(@NonNull final Status that) {
final long diff = getSortId() - that.getSortId();
@ -479,7 +512,12 @@ public class Status extends TwitterResponseObject implements Comparable<Status>,
@OnJsonParseComplete
void afterStatusParsed() throws IOException {
if (id == null || text == null) throw new IOException("Malformed Status object");
if (id == null) {
throw new IOException("Malformed Status object (no id)");
}
if (text == null && fullText == null) {
throw new IOException("Malformed Status object (no text)");
}
fixStatus();
}
@ -492,14 +530,11 @@ public class Status extends TwitterResponseObject implements Comparable<Status>,
}
if (quotedStatus == null && repostStatus != null) {
quotedStatus = repostStatus;
quotedStatusId = repostStatusId;
isQuoteStatus = true;
}
}
public static void setQuotedStatus(Status status, Status quoted) {
if (status == null) return;
status.quotedStatus = quoted;
}
@ParcelablePlease
@JsonObject

View File

@ -55,6 +55,10 @@ public class StatusUpdate extends SimpleValueMap {
put("media_ids", RestFuUtils.toString(mediaIds, ','));
}
public void setAttachmentUrl(final String attachmentUrl) {
put("attachment_url", attachmentUrl);
}
public void setPlaceId(final String placeId) {
put("place_id", placeId);
}
@ -89,6 +93,11 @@ public class StatusUpdate extends SimpleValueMap {
return this;
}
public StatusUpdate attachmentUrl(final String attachmentUrl) {
setAttachmentUrl(attachmentUrl);
return this;
}
public StatusUpdate possiblySensitive(final boolean possiblySensitive) {
setPossiblySensitive(possiblySensitive);
return this;

View File

@ -238,6 +238,9 @@ public class User extends TwitterResponseObject implements Comparable<User>, Par
@JsonField(name = "statusnet_blocking")
boolean statusnetBlocking;
@JsonField(name = "pinned_tweet_ids")
String[] pinnedTweetIds;
public boolean canMediaTag() {
return canMediaTag;
}
@ -528,6 +531,10 @@ public class User extends TwitterResponseObject implements Comparable<User>, Par
return followsYou;
}
public String[] getPinnedTweetIds() {
return pinnedTweetIds;
}
@Override
public String toString() {
return "User{" +

View File

@ -0,0 +1,21 @@
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/5/27.
*/
@Queries({@KeyValue(key = "include_my_retweet", valueKey = "include_my_retweet"),
@KeyValue(key = "include_rts", valueKey = "include_entities"),
@KeyValue(key = "include_entities", valueKey = "include_entities"),
@KeyValue(key = "include_cards", valueKey = "include_cards"),
@KeyValue(key = "cards_platform", valueKey = "cards_platform"),
@KeyValue(key = "include_reply_count", valueKey = "include_reply_count"),
@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")
})
public class StatusAnnotationTemplate {
}

View File

@ -0,0 +1,40 @@
package org.mariotaku.microblog.library.twitter.util;
import org.mariotaku.microblog.library.MicroBlogException;
import org.mariotaku.restfu.RestConverter;
import org.mariotaku.restfu.RestFuUtils;
import org.mariotaku.restfu.http.ContentType;
import org.mariotaku.restfu.http.HttpResponse;
import org.mariotaku.restfu.http.mime.Body;
import org.mariotaku.restfu.oauth.OAuthToken;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.text.ParseException;
/**
* Created by mariotaku on 16/5/21.
*/
public class OAuthTokenResponseConverter implements RestConverter<HttpResponse, OAuthToken, MicroBlogException> {
@Override
public OAuthToken convert(HttpResponse response) throws IOException, ConvertException {
final Body body = response.getBody();
try {
final ContentType contentType = body.contentType();
final ByteArrayOutputStream os = new ByteArrayOutputStream();
body.writeTo(os);
Charset charset = contentType != null ? contentType.getCharset() : null;
if (charset == null) {
charset = Charset.defaultCharset();
}
try {
return new OAuthToken(os.toString(charset.name()), charset);
} catch (ParseException e) {
throw new ConvertException(e);
}
} finally {
RestFuUtils.closeSilently(body);
}
}
}

View File

@ -193,6 +193,9 @@ public interface IntentConstants {
String EXTRA_CURRENT_MEDIA = "current_media";
String EXTRA_EXTRAS = "extras";
String EXTRA_MY_FOLLOWING_ONLY = "my_following_only";
String EXTRA_HIDE_RETWEETS = "hide_retweets";
String EXTRA_HIDE_QUOTES = "hide_quotes";
String EXTRA_HIDE_REPLIES = "hide_replies";
String EXTRA_MENTIONS_ONLY = "mentions_only";
String EXTRA_CHANGED = "changed";
String EXTRA_NOTIFY_CHANGE = "notify_change";

View File

@ -91,14 +91,6 @@ public interface SharedPreferenceConstants {
String VALUE_COMPOSE_NOW_ACTION_TAKE_PHOTO = "take_photo";
String VALUE_COMPOSE_NOW_ACTION_PICK_IMAGE = "pick_image";
String VALUE_CARD_HIGHLIGHT_OPTION_NONE = VALUE_NONE;
String VALUE_CARD_HIGHLIGHT_OPTION_BACKGROUND = "background";
String VALUE_CARD_HIGHLIGHT_OPTION_LINE = "line";
int VALUE_CARD_HIGHLIGHT_OPTION_CODE_NONE = 0x0;
int VALUE_CARD_HIGHLIGHT_OPTION_CODE_BACKGROUND = 0x1;
int VALUE_CARD_HIGHLIGHT_OPTION_CODE_LINE = 0x2;
String DEFAULT_THEME = VALUE_THEME_NAME_LIGHT;
String DEFAULT_THEME_BACKGROUND = VALUE_THEME_BACKGROUND_DEFAULT;
String DEFAULT_THEME_FONT_FAMILY = VALUE_THEME_FONT_FAMILY_REGULAR;
@ -127,7 +119,6 @@ public interface SharedPreferenceConstants {
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)
String KEY_DATABASE_ITEM_LIMIT = "database_item_limit";
@ -147,8 +138,6 @@ public interface SharedPreferenceConstants {
String KEY_THEME_FONT_FAMILY = "theme_font_family";
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = true)
String KEY_DISPLAY_PROFILE_IMAGE = "display_profile_image";
@Preference(type = BOOLEAN)
String KEY_LEFTSIDE_COMPOSE_BUTTON = "leftside_compose_button";
@Preference(type = BOOLEAN, exportable = false, hasDefault = true, defaultBoolean = false)
String KEY_ATTACH_LOCATION = "attach_location";
@Preference(type = BOOLEAN, exportable = false, hasDefault = true, defaultBoolean = true)
@ -234,17 +223,12 @@ public interface SharedPreferenceConstants {
String KEY_DISPLAY_SENSITIVE_CONTENTS = "display_sensitive_contents";
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = true)
String KEY_PHISHING_LINK_WARNING = "phishing_link_warning";
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
String KEY_FAST_SCROLL_THUMB = "fast_scroll_thumb";
@Preference(type = STRING, hasDefault = true, defaultString = VALUE_LINK_HIGHLIGHT_OPTION_NONE)
String KEY_LINK_HIGHLIGHT_OPTION = "link_highlight_option";
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = true)
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)
String KEY_PRELOAD_WIFI_ONLY = "preload_wifi_only";
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = true)
String KEY_LINK_TO_QUOTED_TWEET = "link_to_quoted_tweet";
@Preference(type = BOOLEAN)
String KEY_NO_CLOSE_AFTER_TWEET_SENT = "no_close_after_tweet_sent";
@Preference(type = STRING, hasDefault = false)
@ -262,8 +246,6 @@ public interface SharedPreferenceConstants {
String KEY_SETTINGS_WIZARD_COMPLETED = "settings_wizard_completed";
String KEY_CONSUMER_KEY_SECRET_SET = "consumer_key_secret_set";
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = true)
String KEY_CARD_ANIMATION = "card_animation";
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = true)
String KEY_UNREAD_COUNT = "unread_count";
String KEY_NOTIFICATION = "notification";
String KEY_NOTIFICATION_TYPE_HOME = "notification_type_home";
@ -274,8 +256,6 @@ public interface SharedPreferenceConstants {
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
String KEY_PEBBLE_NOTIFICATIONS = "pebble_notifications";
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
String KEY_COMPACT_CARDS = "compact_cards";
@Preference(type = STRING, hasDefault = true, defaultString = VALUE_COMPOSE_NOW_ACTION_COMPOSE)
String KEY_COMPOSE_NOW_ACTION = "compose_now_action";
@ -293,8 +273,6 @@ public interface SharedPreferenceConstants {
String KEY_TRANSLATION_DESTINATION = "translation_destination";
@Preference(type = STRING)
String KEY_TAB_DISPLAY_OPTION = "tab_display_option";
@Preference(type = STRING)
String KEY_CARD_HIGHLIGHT_OPTION = "card_highlight_option";
@Preference(type = INT, exportable = false)
String KEY_LIVE_WALLPAPER_SCALE = "live_wallpaper_scale";
@Preference(type = LONG, exportable = false)
@ -319,8 +297,6 @@ public interface SharedPreferenceConstants {
String KEY_BUG_REPORTS = "bug_reports";
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
String KEY_COMBINED_NOTIFICATIONS = "combined_notifications";
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = true)
String KEY_TWITTER_OPTIMIZED_SEARCHES = "twitter_optimized_searches";
@Preference(type = BOOLEAN, hasDefault = true, defaultBoolean = false)
String KEY_I_WANT_MY_STARS_BACK = "i_want_my_stars_back";
@Preference(type = STRING, hasDefault = false)

View File

@ -33,22 +33,23 @@ import org.mariotaku.library.objectcursor.annotation.CursorObject;
import org.mariotaku.twidere.model.draft.ActionExtra;
import org.mariotaku.twidere.model.util.DraftExtrasConverter;
import org.mariotaku.twidere.model.util.UserKeysCursorFieldConverter;
import org.mariotaku.twidere.provider.TwidereDataStore;
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@ParcelablePlease
@CursorObject(valuesCreator = true)
@CursorObject(valuesCreator = true, tableInfo = true)
public class Draft implements Parcelable {
@ParcelableThisPlease
@CursorField(value = Drafts.ACCOUNT_IDS, converter = UserKeysCursorFieldConverter.class)
public UserKey[] account_ids;
@ParcelableThisPlease
@CursorField(value = Drafts._ID, excludeWrite = true)
@CursorField(value = Drafts._ID, type = TwidereDataStore.TYPE_PRIMARY_KEY, excludeWrite = true)
public long _id;
@ParcelableThisPlease
@CursorField(value = Drafts.ACCOUNT_KEYS, converter = UserKeysCursorFieldConverter.class)
public UserKey[] account_keys;
@ParcelableThisPlease
@CursorField(Drafts.TIMESTAMP)
public long timestamp;
@ParcelableThisPlease

View File

@ -17,16 +17,23 @@ public class MediaUploadResult implements Parcelable {
@ParcelableThisPlease
@JsonField(name = "media_uris")
public String[] media_uris;
@ParcelableThisPlease
@JsonField(name = "error_code")
public int error_code;
@ParcelableThisPlease
@JsonField(name = "error_message")
public String error_message;
@ParcelableThisPlease
@JsonField(name = "extras")
public String extras;
@ParcelableThisPlease
@JsonField(name = "shared_owners")
public UserKey[] shared_owners;
public static final Creator<MediaUploadResult> CREATOR = new Creator<MediaUploadResult>() {
@Override
public MediaUploadResult createFromParcel(Parcel source) {

View File

@ -33,15 +33,19 @@ import org.mariotaku.library.objectcursor.annotation.CursorField;
import org.mariotaku.library.objectcursor.annotation.CursorObject;
import org.mariotaku.twidere.model.util.UserKeyConverter;
import org.mariotaku.twidere.model.util.UserKeyCursorFieldConverter;
import org.mariotaku.twidere.provider.TwidereDataStore;
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages;
import java.util.Arrays;
@ParcelablePlease(allFields = false)
@JsonObject
@CursorObject(valuesCreator = true)
@CursorObject(valuesCreator = true, tableInfo = true)
public class ParcelableDirectMessage implements Parcelable, Comparable<ParcelableDirectMessage> {
@ParcelableThisPlease
@CursorField(value = DirectMessages._ID, type = TwidereDataStore.TYPE_PRIMARY_KEY, excludeWrite = true)
public long _id;
@ParcelableThisPlease
@JsonField(name = "account_id", typeConverter = UserKeyConverter.class)
@CursorField(value = DirectMessages.ACCOUNT_KEY, converter = UserKeyCursorFieldConverter.class)
@ -70,17 +74,18 @@ public class ParcelableDirectMessage implements Parcelable, Comparable<Parcelabl
public boolean is_outgoing;
@ParcelableThisPlease
@JsonField(name = "text_html")
@CursorField(DirectMessages.TEXT_HTML)
public String text_html;
@JsonField(name = "text_unescaped")
@CursorField(DirectMessages.TEXT_UNESCAPED)
public String text_unescaped;
@ParcelableThisPlease
@JsonField(name = "text_plain")
@CursorField(DirectMessages.TEXT_PLAIN)
public String text_plain;
@ParcelableThisPlease
@JsonField(name = "text_unescaped")
@CursorField(DirectMessages.TEXT_UNESCAPED)
public String text_unescaped;
@JsonField(name = "spans")
@CursorField(value = DirectMessages.SPANS, converter = LoganSquareCursorFieldConverter.class)
public SpanItem[] spans;
@ParcelableThisPlease
@JsonField(name = "sender_name")
@ -108,6 +113,11 @@ public class ParcelableDirectMessage implements Parcelable, Comparable<Parcelabl
@CursorField(DirectMessages.RECIPIENT_PROFILE_IMAGE_URL)
public String recipient_profile_image_url;
@ParcelableThisPlease
@JsonField(name = "conversation_id")
@CursorField(DirectMessages.CONVERSATION_ID)
public String conversation_id;
@ParcelableThisPlease
@JsonField(name = "media")
@CursorField(value = DirectMessages.MEDIA_JSON, converter = LoganSquareCursorFieldConverter.class)
@ -147,14 +157,14 @@ public class ParcelableDirectMessage implements Parcelable, Comparable<Parcelabl
public String toString() {
return "ParcelableDirectMessage{" +
"account_key=" + account_key +
", id=" + id +
", id='" + id + '\'' +
", timestamp=" + timestamp +
", sender_id=" + sender_id +
", recipient_id=" + recipient_id +
", sender_id='" + sender_id + '\'' +
", recipient_id='" + recipient_id + '\'' +
", is_outgoing=" + is_outgoing +
", text_html='" + text_html + '\'' +
", text_plain='" + text_plain + '\'' +
", text_unescaped='" + text_unescaped + '\'' +
", text_plain='" + text_plain + '\'' +
", spans=" + Arrays.toString(spans) +
", sender_name='" + sender_name + '\'' +
", recipient_name='" + recipient_name + '\'' +
", sender_screen_name='" + sender_screen_name + '\'' +

View File

@ -0,0 +1,36 @@
package org.mariotaku.twidere.model;
import org.mariotaku.commons.objectcursor.LoganSquareCursorFieldConverter;
import org.mariotaku.library.objectcursor.annotation.CursorField;
import org.mariotaku.library.objectcursor.annotation.CursorObject;
import org.mariotaku.twidere.model.util.UserKeyCursorFieldConverter;
import org.mariotaku.twidere.provider.TwidereDataStore;
import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations;
/**
* Created by mariotaku on 16/6/6.
*/
@CursorObject(tableInfo = true, valuesCreator = true)
public class ParcelableMessageConversation {
@CursorField(value = Conversations._ID, type = TwidereDataStore.TYPE_PRIMARY_KEY)
public long _id;
@CursorField(Conversations.CONVERSATION_ID)
public String id;
@CursorField(value = Conversations.ACCOUNT_KEY, converter = UserKeyCursorFieldConverter.class)
public UserKey account_key;
@CursorField(value = Conversations.LAST_SEND_AT)
public long last_send_at;
@CursorField(Conversations.TEXT_UNESCAPED)
public String text_unescaped;
@CursorField(value = Conversations.MEDIA_JSON, converter = LoganSquareCursorFieldConverter.class)
public ParcelableMedia[] media;
@CursorField(value = Conversations.PARTICIPANTS, converter = LoganSquareCursorFieldConverter.class)
public ParcelableUser[] participants;
@CursorField(value = Conversations.SENDER_KEY, converter = UserKeyCursorFieldConverter.class)
public UserKey sender_key;
@CursorField(value = Conversations.RECIPIENT_KEY, converter = UserKeyCursorFieldConverter.class)
public UserKey recipient_key;
@CursorField(value = Conversations.REQUEST_CURSOR)
public String request_cursor;
}

View File

@ -1,25 +0,0 @@
package org.mariotaku.twidere.model;
import org.mariotaku.library.objectcursor.annotation.CursorField;
import org.mariotaku.library.objectcursor.annotation.CursorObject;
import org.mariotaku.twidere.model.util.UserKeyCursorFieldConverter;
import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Entries;
/**
* Created by mariotaku on 16/3/28.
*/
@CursorObject
public class ParcelableMessageEntry {
@CursorField(value = Entries._ID, excludeWrite = true)
public long id;
@CursorField(value = Entries.ACCOUNT_KEY, converter = UserKeyCursorFieldConverter.class)
public UserKey account_key;
@CursorField(value = Entries.CONVERSATION_ID)
public String conversation_id;
@CursorField(value = Entries.UPDATED_AT)
public long updated_at;
@CursorField(value = Entries.TEXT_CONTENT)
public String text_content;
}

View File

@ -543,6 +543,14 @@ public class ParcelableStatus implements Parcelable, Comparable<ParcelableStatus
@JsonField(name = "user_statusnet_profile_url")
@ParcelableThisPlease
public String user_statusnet_profile_url;
@JsonField(name = "display_text_range")
@ParcelableThisPlease
@Nullable
public int[] display_text_range;
@JsonField(name = "quoted_display_text_range")
@ParcelableThisPlease
@Nullable
public int[] quoted_display_text_range;
@Override
public int describeContents() {

View File

@ -60,6 +60,9 @@ public class ParcelableStatusUpdate implements Parcelable {
@JsonField(name = "repost_status_id")
@ParcelableThisPlease
public String repost_status_id;
@JsonField(name = "attachment_url")
@ParcelableThisPlease
public String attachment_url;
public ParcelableStatusUpdate() {
}

View File

@ -25,6 +25,7 @@ import android.support.annotation.NonNull;
import com.bluelinelabs.logansquare.annotation.JsonField;
import com.bluelinelabs.logansquare.annotation.JsonObject;
import com.hannesdorfmann.parcelableplease.annotation.ParcelableNoThanks;
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease;
@ -34,12 +35,15 @@ import org.mariotaku.library.objectcursor.annotation.CursorField;
import org.mariotaku.library.objectcursor.annotation.CursorObject;
import org.mariotaku.twidere.model.util.UserKeyConverter;
import org.mariotaku.twidere.model.util.UserKeyCursorFieldConverter;
import org.mariotaku.twidere.provider.TwidereDataStore;
import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers;
import java.util.Arrays;
@ParcelablePlease(allFields = false)
@JsonObject
@CursorObject(valuesCreator = true)
@CursorObject(valuesCreator = true, tableInfo = true)
public class ParcelableUser implements Parcelable, Comparable<ParcelableUser> {
@ParcelableThisPlease
@ -49,6 +53,10 @@ public class ParcelableUser implements Parcelable, Comparable<ParcelableUser> {
@ParcelableThisPlease
public int account_color;
@ParcelableThisPlease
@CursorField(value = CachedUsers._ID, type = TwidereDataStore.TYPE_PRIMARY_KEY, excludeWrite = true)
public long _id;
@ParcelableThisPlease
@JsonField(name = "id", typeConverter = UserKeyConverter.class)
@CursorField(value = CachedUsers.USER_KEY, converter = UserKeyCursorFieldConverter.class)
@ -114,17 +122,14 @@ public class ParcelableUser implements Parcelable, Comparable<ParcelableUser> {
@CursorField(CachedUsers.URL_EXPANDED)
public String url_expanded;
@ParcelableThisPlease
@JsonField(name = "description_html")
@CursorField(CachedUsers.DESCRIPTION_HTML)
public String description_html;
@ParcelableThisPlease
@JsonField(name = "description_unescaped")
@CursorField(CachedUsers.DESCRIPTION_UNESCAPED)
public String description_unescaped;
@ParcelableThisPlease
@JsonField(name = "description_expanded")
@CursorField(CachedUsers.DESCRIPTION_EXPANDED)
public String description_expanded;
@JsonField(name = "description_spans")
@CursorField(value = CachedUsers.DESCRIPTION_SPANS, converter = LoganSquareCursorFieldConverter.class)
public SpanItem[] description_spans;
@ParcelableThisPlease
@JsonField(name = "followers_count")
@ -176,6 +181,14 @@ public class ParcelableUser implements Parcelable, Comparable<ParcelableUser> {
@CursorField(value = CachedUsers.EXTRAS, converter = LoganSquareCursorFieldConverter.class)
public Extras extras;
@ParcelableNoThanks
@CursorField(CachedUsers.LAST_SEEN)
public long last_seen;
@ParcelableNoThanks
@CursorField(value = CachedUsers.SCORE, excludeWrite = true)
public int score;
@ParcelableThisPlease
public int color;
@ParcelableThisPlease
@ -272,9 +285,8 @@ public class ParcelableUser implements Parcelable, Comparable<ParcelableUser> {
", profile_background_url='" + profile_background_url + '\'' +
", url='" + url + '\'' +
", url_expanded='" + url_expanded + '\'' +
", description_html='" + description_html + '\'' +
", description_unescaped='" + description_unescaped + '\'' +
", description_expanded='" + description_expanded + '\'' +
", description_spans=" + Arrays.toString(description_spans) +
", followers_count=" + followers_count +
", friends_count=" + friends_count +
", statuses_count=" + statuses_count +

View File

@ -7,6 +7,7 @@ import android.text.style.URLSpan;
import com.bluelinelabs.logansquare.annotation.JsonField;
import com.bluelinelabs.logansquare.annotation.JsonObject;
import com.hannesdorfmann.parcelableplease.annotation.ParcelableNoThanks;
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease;
@ -40,12 +41,19 @@ public class SpanItem implements Parcelable {
@ParcelableThisPlease
public String link;
@ParcelableNoThanks
public int orig_start = -1;
@ParcelableNoThanks
public int orig_end = -1;
@Override
public String toString() {
return "SpanItem{" +
"start=" + start +
", end=" + end +
", link='" + link + '\'' +
", orig_start=" + orig_start +
", orig_end=" + orig_end +
'}';
}

View File

@ -28,6 +28,10 @@ public class StatusShortenResult implements Parcelable {
@ParcelableThisPlease
public String error_message;
@ParcelableThisPlease
@JsonField(name = "shared_owners")
public UserKey[] shared_owners;
public StatusShortenResult() {
}

View File

@ -23,8 +23,11 @@ import android.content.ContentResolver;
import android.net.Uri;
import android.provider.BaseColumns;
import org.mariotaku.twidere.model.DraftTableInfo;
import org.mariotaku.twidere.model.ParcelableActivityTableInfo;
import org.mariotaku.twidere.model.ParcelableDirectMessageTableInfo;
import org.mariotaku.twidere.model.ParcelableStatusTableInfo;
import org.mariotaku.twidere.model.ParcelableUserTableInfo;
@SuppressWarnings("unused")
public interface TwidereDataStore {
@ -252,11 +255,9 @@ public interface TwidereDataStore {
String DESCRIPTION_PLAIN = "description_plain";
String DESCRIPTION_HTML = "description_html";
String DESCRIPTION_UNESCAPED = "description_unescaped";
String DESCRIPTION_EXPANDED = "description_expanded";
String DESCRIPTION_SPANS = "description_spans";
String LOCATION = "location";
@ -303,20 +304,11 @@ public interface TwidereDataStore {
String EXTRAS = "extras";
String[] COLUMNS = {_ID, USER_KEY, CREATED_AT, NAME, SCREEN_NAME, DESCRIPTION_PLAIN, LOCATION,
URL, PROFILE_IMAGE_URL, PROFILE_BANNER_URL, PROFILE_BACKGROUND_URL, IS_PROTECTED,
IS_VERIFIED, IS_FOLLOWING, FOLLOWERS_COUNT, FRIENDS_COUNT, STATUSES_COUNT,
FAVORITES_COUNT, LISTED_COUNT, MEDIA_COUNT, DESCRIPTION_HTML, DESCRIPTION_EXPANDED,
URL_EXPANDED, BACKGROUND_COLOR, LINK_COLOR, TEXT_COLOR, LAST_SEEN,
DESCRIPTION_UNESCAPED, EXTRAS};
String[] COLUMNS = ParcelableUserTableInfo.COLUMNS;
String[] BASIC_COLUMNS = {_ID, USER_KEY, NAME, SCREEN_NAME, PROFILE_IMAGE_URL};
String[] TYPES = {TYPE_PRIMARY_KEY, TYPE_TEXT_NOT_NULL, TYPE_INT, TYPE_TEXT, TYPE_TEXT,
TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_BOOLEAN,
TYPE_BOOLEAN, TYPE_BOOLEAN, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT,
TYPE_INT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT,
TYPE_TEXT, TYPE_TEXT};
String[] TYPES = ParcelableUserTableInfo.TYPES;
}
@ -382,10 +374,15 @@ public interface TwidereDataStore {
interface Messages extends BaseColumns, InsertedDateColumns, AccountSupportColumns {
interface Entries extends BaseColumns, InsertedDateColumns, AccountSupportColumns {
interface Conversations extends BaseColumns, AccountSupportColumns {
String CONVERSATION_ID = "conversation_id";
String UPDATED_AT = "updated_at";
String TEXT_CONTENT = "text_content";
String TEXT_UNESCAPED = "text_unescaped";
String LAST_SEND_AT = "last_send_at";
String MEDIA_JSON = "media_json";
String PARTICIPANTS = "participants";
String SENDER_KEY = "sender_key";
String RECIPIENT_KEY = "recipient_key";
String REQUEST_CURSOR = "request_cursor";
}
}
@ -404,9 +401,9 @@ public interface TwidereDataStore {
String IS_OUTGOING = "is_outgoing";
String TEXT_HTML = "text_html";
String TEXT_PLAIN = "text_plain";
String TEXT_UNESCAPED = "text_unescaped";
String SPANS = "spans";
String SENDER_NAME = "sender_name";
String RECIPIENT_NAME = "recipient_name";
String SENDER_SCREEN_NAME = "sender_screen_name";
@ -416,13 +413,8 @@ public interface TwidereDataStore {
String MEDIA_JSON = "media_json";
String[] COLUMNS = {_ID, ACCOUNT_KEY, MESSAGE_ID, MESSAGE_TIMESTAMP,
SENDER_ID, RECIPIENT_ID, CONVERSATION_ID, IS_OUTGOING, TEXT_HTML, TEXT_PLAIN, TEXT_UNESCAPED,
SENDER_NAME, RECIPIENT_NAME, SENDER_SCREEN_NAME, RECIPIENT_SCREEN_NAME, SENDER_PROFILE_IMAGE_URL,
RECIPIENT_PROFILE_IMAGE_URL, MEDIA_JSON, INSERTED_DATE};
String[] TYPES = {TYPE_PRIMARY_KEY, TYPE_TEXT_NOT_NULL, TYPE_TEXT_NOT_NULL, TYPE_INT,
TYPE_TEXT_NOT_NULL, TYPE_TEXT_NOT_NULL, TYPE_INT, TYPE_BOOLEAN, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT,
TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT, INSERTED_DATE_TYPE};
String[] COLUMNS = ParcelableDirectMessageTableInfo.COLUMNS;
String[] TYPES = ParcelableDirectMessageTableInfo.TYPES;
String DEFAULT_SORT_ORDER = MESSAGE_ID + " DESC";
@ -460,7 +452,7 @@ public interface TwidereDataStore {
String NAME = "name";
String SCREEN_NAME = "screen_name";
String PROFILE_IMAGE_URL = "profile_image_url";
String TEXT_HTML = DirectMessages.TEXT_HTML;
String TEXT_UNESCAPED = "text_unescaped";
String CONVERSATION_ID = "conversation_id";
int IDX__ID = 0;
@ -471,7 +463,7 @@ public interface TwidereDataStore {
int IDX_NAME = 5;
int IDX_SCREEN_NAME = 6;
int IDX_PROFILE_IMAGE_URL = 7;
int IDX_TEXT = 8;
int IDX_TEXT_UNESCAPED = 8;
int IDX_CONVERSATION_ID = 9;
}
@ -571,9 +563,7 @@ public interface TwidereDataStore {
* Account IDs of unsent status.<br>
* Type: TEXT
*/
String ACCOUNT_IDS = "account_ids";
String ACCOUNT_KEYS = "account_keys";
String ACCOUNT_KEYS = "account_ids";
String LOCATION = "location";
@ -589,11 +579,9 @@ public interface TwidereDataStore {
String ACTION_EXTRAS = "action_extras";
String[] COLUMNS = {_ID, TEXT, ACCOUNT_IDS, LOCATION, MEDIA,
IN_REPLY_TO_STATUS_ID, IS_POSSIBLY_SENSITIVE, TIMESTAMP, ACTION_TYPE, ACTION_EXTRAS};
String[] COLUMNS = DraftTableInfo.COLUMNS;
String[] TYPES = {TYPE_PRIMARY_KEY, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT,
TYPE_INT, TYPE_INT, TYPE_BOOLEAN, TYPE_INT, TYPE_TEXT, TYPE_TEXT};
String[] TYPES = DraftTableInfo.TYPES;
}

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="status_shortener_service_interface_version">3</string>
<string name="media_uploader_service_interface_version">2</string>
<string name="media_uploader_service_interface_version">3</string>
</resources>

View File

@ -22,7 +22,7 @@ apply plugin: 'com.android.library'
android {
defaultConfig {
minSdkVersion 14
targetSdkVersion 23
targetSdkVersion 24
versionCode 1
versionName "1.0"
}

View File

@ -23,7 +23,7 @@ android {
defaultConfig {
applicationId "org.mariotaku.twidere.donate.nyanwp"
minSdkVersion 20
targetSdkVersion 23
targetSdkVersion 24
versionCode 1
versionName "1.0"
}

View File

@ -23,7 +23,7 @@ android {
defaultConfig {
applicationId "org.mariotaku.twidere.donate.nyanwp"
minSdkVersion 14
targetSdkVersion 23
targetSdkVersion 24
versionCode 3
versionName "1.2"
}

View File

@ -22,7 +22,7 @@ apply plugin: 'com.android.library'
android {
defaultConfig {
minSdkVersion 14
targetSdkVersion 23
targetSdkVersion 24
versionCode 1
versionName "1.0"
}

View File

@ -12,6 +12,7 @@ import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.model.ParcelableStatusUpdate;
import org.mariotaku.twidere.model.UploaderMediaItem;
import org.mariotaku.commons.logansquare.LoganSquareMapperFinder;
import org.mariotaku.twidere.model.UserKey;
import java.io.IOException;
import java.lang.ref.WeakReference;
@ -32,7 +33,7 @@ public abstract class MediaUploaderService extends Service {
}
protected abstract MediaUploadResult upload(ParcelableStatusUpdate status,
UploaderMediaItem[] media);
UserKey currentAccount, UploaderMediaItem[] media);
protected abstract boolean callback(MediaUploadResult result, ParcelableStatus status);
@ -50,13 +51,15 @@ public abstract class MediaUploaderService extends Service {
}
@Override
public String upload(String statusJson, String mediaJson) throws RemoteException {
public String upload(String statusJson, String currentAccount, String mediaJson) throws RemoteException {
try {
final ParcelableStatusUpdate statusUpdate = LoganSquareMapperFinder.mapperFor(ParcelableStatusUpdate.class)
.parse(statusJson);
final List<UploaderMediaItem> media = LoganSquareMapperFinder.mapperFor(UploaderMediaItem.class)
.parseList(mediaJson);
final MediaUploadResult shorten = mService.get().upload(statusUpdate, media.toArray(new UploaderMediaItem[media.size()]));
final MediaUploadResult shorten = mService.get().upload(statusUpdate,
UserKey.valueOf(currentAccount),
media.toArray(new UploaderMediaItem[media.size()]));
return LoganSquareMapperFinder.mapperFor(MediaUploadResult.class).serialize(shorten);
} catch (IOException e) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {

View File

@ -23,7 +23,7 @@ android {
defaultConfig {
applicationId "org.mariotaku.twidere"
minSdkVersion 20
targetSdkVersion 23
targetSdkVersion 24
versionCode 1
versionName "1.0"
multiDexEnabled true
@ -39,5 +39,5 @@ android {
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.google.android.support:wearable:1.3.0'
compile 'com.google.android.gms:play-services-wearable:8.4.0'
compile 'com.google.android.gms:play-services-wearable:9.0.2'
}

View File

@ -27,13 +27,11 @@ android {
defaultConfig {
applicationId "org.mariotaku.twidere"
minSdkVersion 14
targetSdkVersion 23
versionCode 196
versionName "3.1.7"
targetSdkVersion 24
versionCode 198
versionName "3.1.9"
multiDexEnabled true
generatedDensities = []
buildConfigField 'boolean', 'LEAK_CANARY_ENABLED', 'Boolean.parseBoolean("false")'
buildConfigField 'boolean', 'SHOW_CUSTOM_TOKEN_DIALOG', 'Boolean.parseBoolean("false")'
@ -96,18 +94,14 @@ dependencies {
compile('com.github.mariotaku:app-theme-engine:1efc6237e1@aar') {
transitive = true
}
compile('com.github.mariotaku.material-dialogs:commons:bf2f2c5c57@aar') {
transitive = true
}
compile project(':twidere.component.common')
compile project(':twidere.component.nyan')
// START Non-FOSS component
googleCompile 'com.google.android.gms:play-services-maps:8.4.0'
googleCompile 'com.google.android.gms:play-services-auth:8.4.0'
googleCompile 'com.google.android.gms:play-services-measurement:8.4.0'
googleCompile 'com.google.android.gms:play-services-maps:9.0.2'
googleCompile 'com.google.android.gms:play-services-auth:9.0.2'
googleCompile 'com.google.maps.android:android-maps-utils:0.4.3'
googleCompile('com.crashlytics.sdk.android:crashlytics:2.5.5@aar') { transitive = true }
googleCompile ':YouTubeAndroidPlayerApi:1.2.2@jar'
@ -123,17 +117,17 @@ dependencies {
testCompile 'junit:junit:4.12'
androidTestCompile 'com.android.support:support-annotations:23.4.0'
androidTestCompile 'com.android.support:support-annotations:24.0.0'
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'com.android.support.test:rules:0.5'
compile 'com.android.support:multidex:1.0.1'
compile 'com.android.support:support-v13:23.4.0'
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:cardview-v7:23.4.0'
compile 'com.android.support:recyclerview-v7:23.4.0'
compile 'com.android.support:preference-v7:23.4.0'
compile 'com.android.support:preference-v14:23.4.0'
compile 'com.android.support:support-v13:24.0.0'
compile 'com.android.support:appcompat-v7:24.0.0'
compile 'com.android.support:cardview-v7:24.0.0'
compile 'com.android.support:recyclerview-v7:24.0.0'
compile 'com.android.support:preference-v7:24.0.0'
compile 'com.android.support:preference-v14:24.0.0'
compile 'com.twitter:twitter-text:1.13.0'
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
compile 'com.davemorrissey.labs:subsampling-scale-image-view:3.5.0'
@ -143,7 +137,6 @@ dependencies {
compile 'com.commonsware.cwac:layouts:0.4.2'
compile 'com.rengwuxian.materialedittext:library:2.1.4'
compile 'com.pnikosis:materialish-progress:1.7'
compile 'com.github.johnpersano:supertoasts:1.3.4.1@aar'
compile 'com.github.mariotaku:MessageBubbleView:1.2'
compile 'com.github.mariotaku:DragSortListView:0.6.1'
compile 'com.github.uucky:ColorPicker-Android:0.9.7@aar'
@ -157,7 +150,8 @@ dependencies {
compile 'com.soundcloud.android:android-crop:1.0.1@aar'
compile 'com.hannesdorfmann.parcelableplease:annotation:1.0.2'
compile 'com.github.mariotaku:PickNCrop:0.9.4'
compile 'com.github.mariotaku.RestFu:okhttp3:0.9.27'
compile 'com.github.mariotaku.RestFu:library:0.9.29'
compile 'com.github.mariotaku.RestFu:okhttp3:0.9.29'
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.lnikkila:extendedtouchview:0.1.0'
compile 'com.google.dagger:dagger:2.1'
@ -166,9 +160,10 @@ dependencies {
compile 'com.github.mariotaku.MediaViewerLibrary:subsample-image-view:0.9.17'
compile 'com.github.mariotaku.SQLiteQB:library:0.9.6'
compile 'com.github.mariotaku.ObjectCursor:core:0.9.9'
compile 'com.github.mariotaku:MultiValueSwitch:0.9.4'
compile 'com.github.mariotaku:AbstractTask:0.9.1'
compile 'com.github.mariotaku.CommonsLibrary:parcel:0.9.4'
compile 'com.github.mariotaku:MultiValueSwitch:0.9.6'
compile 'com.github.mariotaku:AbstractTask:0.9.2'
compile 'com.github.mariotaku.CommonsLibrary:parcel:0.9.8'
compile 'com.github.mariotaku.CommonsLibrary:io:0.9.8'
}
task svgToDrawable(type: SvgDrawableTask) {

View File

@ -3,7 +3,7 @@ IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- twidere/build.gradle (date 1463193773000)
--- twidere/build.gradle (date 1467162711000)
+++ twidere/build.gradle (revision )
@@ -5,19 +5,19 @@
apply plugin: 'androidsvgdrawable'
@ -28,7 +28,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
// END Non-FOSS component
}
}
@@ -49,7 +49,7 @@
@@ -47,7 +47,7 @@
productFlavors {
// START Non-FOSS component
@ -37,7 +37,7 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
// END Non-FOSS component
fdroid {}
}
@@ -79,7 +79,7 @@
@@ -77,7 +77,7 @@
repositories {
maven { url 'https://s3.amazonaws.com/repo.commonsware.com' }
// START Non-FOSS component
@ -46,26 +46,24 @@ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
// END Non-FOSS component
flatDir { dirs "$projectDir/lib" }
}
@@ -105,12 +105,12 @@
@@ -100,11 +100,11 @@
compile project(':twidere.component.nyan')
// START Non-FOSS component
- googleCompile 'com.google.android.gms:play-services-maps:8.4.0'
- googleCompile 'com.google.android.gms:play-services-auth:8.4.0'
- googleCompile 'com.google.android.gms:play-services-measurement:8.4.0'
- googleCompile 'com.google.android.gms:play-services-maps:9.0.2'
- googleCompile 'com.google.android.gms:play-services-auth:9.0.2'
- googleCompile 'com.google.maps.android:android-maps-utils:0.4.3'
- googleCompile('com.crashlytics.sdk.android:crashlytics:2.5.5@aar') { transitive = true }
- googleCompile ':YouTubeAndroidPlayerApi:1.2.2@jar'
+// googleCompile 'com.google.android.gms:play-services-maps:8.4.0'
+// googleCompile 'com.google.android.gms:play-services-auth:8.4.0'
+// googleCompile 'com.google.android.gms:play-services-measurement:8.4.0'
+// googleCompile 'com.google.android.gms:play-services-maps:9.0.2'
+// googleCompile 'com.google.android.gms:play-services-auth:9.0.2'
+// googleCompile 'com.google.maps.android:android-maps-utils:0.4.3'
+// googleCompile('com.crashlytics.sdk.android:crashlytics:2.5.5@aar') { transitive = true }
+// googleCompile ':YouTubeAndroidPlayerApi:1.2.2@jar'
// END Non-FOSS component
fdroidCompile 'org.osmdroid:osmdroid-android:5.1'
@@ -204,5 +204,5 @@
@@ -199,5 +199,5 @@
}
// START Non-FOSS component

View File

@ -3,7 +3,6 @@ package org.mariotaku.twidere.activity;
import android.net.Uri;
import org.junit.Test;
import org.mariotaku.twidere.activity.MediaViewerActivity;
import static org.junit.Assert.assertEquals;

View File

@ -2,7 +2,6 @@ package org.mariotaku.twidere.util;
import org.junit.Test;
import org.mariotaku.twidere.util.UriUtils;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNull;

View File

@ -72,6 +72,7 @@
android:hardwareAccelerated="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:resizeableActivity="true"
android:supportsRtl="true"
android:theme="@style/Theme.Twidere.NoActionBar"
tools:ignore="UnusedAttribute">

View File

@ -24,7 +24,7 @@ import android.content.SharedPreferences;
import android.net.Uri;
import android.util.Log;
import org.mariotaku.restfu.RestFuUtils;
import org.mariotaku.commons.io.StreamUtils;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.util.Utils;
@ -114,7 +114,7 @@ public class UploadLogsTask implements Runnable {
conn.setDoOutput(true);
os = conn.getOutputStream();
is = new FileInputStream(logFile);
RestFuUtils.copyStream(is, os);
StreamUtils.copy(is, os, null, null);
final int responseCode = conn.getResponseCode();
if (responseCode >= 200 && responseCode < 300) {
uploadLogEvent.finish(conn);

View File

@ -21,6 +21,7 @@ package edu.tsinghua.hotmobi.model;
import android.content.Context;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import com.bluelinelabs.logansquare.annotation.JsonField;
import com.bluelinelabs.logansquare.annotation.JsonObject;
@ -77,7 +78,7 @@ public abstract class BaseEvent implements Parcelable, LogModel {
this.location = location;
}
public void markStart(Context context) {
public void markStart(@NonNull Context context) {
setStartTime(System.currentTimeMillis());
setTimeOffset(TimeZone.getDefault().getOffset(startTime));
setLocation(LocationUtils.getCachedLatLng(context));

View File

@ -49,7 +49,7 @@ public class LinkEvent extends BaseEvent implements Parcelable {
}
public static LinkEvent create(Context context, String link, int typeInt) {
public static LinkEvent create(@NonNull Context context, String link, int typeInt) {
final LinkEvent event = new LinkEvent();
event.markStart(context);
event.setLink(link);

View File

@ -88,7 +88,7 @@ public class MediaDownloadEvent extends BaseEvent implements Parcelable {
"} " + super.toString();
}
public static MediaDownloadEvent create(Context context, ParcelableMedia media, long nonce) {
public static MediaDownloadEvent create(@NonNull Context context, ParcelableMedia media, long nonce) {
final MediaDownloadEvent event = new MediaDownloadEvent();
event.markStart(context);
event.setMedia(media);

View File

@ -71,7 +71,8 @@ public class MediaEvent extends BaseEvent implements Parcelable {
@ParcelableThisPlease
boolean previewEnabled;
public static MediaEvent create(Context context, ParcelableStatus status,@NonNull ParcelableMedia media,
public static MediaEvent create(@NonNull Context context, ParcelableStatus status,
@NonNull ParcelableMedia media,
@TimelineType String timelineType, boolean previewEnabled) {
final MediaEvent event = new MediaEvent();
event.markStart(context);

View File

@ -42,7 +42,7 @@ public class NetworkEvent extends BaseEvent implements Parcelable {
@ParcelableThisPlease
int networkType;
public static NetworkEvent create(Context context) {
public static NetworkEvent create(@NonNull Context context) {
final NetworkEvent event = new NetworkEvent();
event.markStart(context);
event.setNetworkType(getActivateNetworkType(context));

View File

@ -75,7 +75,7 @@ public class NotificationEvent extends BaseEvent implements Parcelable {
public NotificationEvent() {
}
public static NotificationEvent create(Context context, @Action String action, long postTime,
public static NotificationEvent create(@NonNull Context context, @Action String action, long postTime,
long respondTime, String type, String accountId, long itemId,
long itemUserId, boolean itemUserFollowing) {
final NotificationEvent event = new NotificationEvent();
@ -93,14 +93,14 @@ public class NotificationEvent extends BaseEvent implements Parcelable {
return event;
}
public static NotificationEvent deleted(Context context, long postTime, String type,
public static NotificationEvent deleted(@NonNull Context context, long postTime, String type,
UserKey accountKey, long itemId, long itemUserId,
boolean itemUserFollowing) {
return create(context, Action.DELETE, System.currentTimeMillis(), postTime, type, accountKey.getId(),
itemId, itemUserId, itemUserFollowing);
}
public static NotificationEvent open(Context context, long postTime, String type, String accountId,
public static NotificationEvent open(@NonNull Context context, long postTime, String type, String accountId,
long itemId, long itemUserId, boolean itemUserFollowing) {
return create(context, Action.OPEN, System.currentTimeMillis(), postTime, type, accountId,
itemId, itemUserId, itemUserFollowing);

View File

@ -46,7 +46,7 @@ public class RefreshEvent extends BaseEvent implements Parcelable {
@TimelineType
String timelineType;
public static RefreshEvent create(final Context context, String[] ids, @TimelineType String timelineType) {
public static RefreshEvent create(@NonNull final Context context, String[] ids, @TimelineType String timelineType) {
final RefreshEvent event = new RefreshEvent();
event.markStart(context);
event.setIds(ids);

View File

@ -4,6 +4,7 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.location.Location;
import android.os.AsyncTask;
import android.support.annotation.NonNull;
import android.util.Log;
import org.mariotaku.twidere.BuildConfig;
@ -23,7 +24,7 @@ public class LocationUtils implements HotMobiConstants, Constants {
private LocationUtils() {
}
public static LatLng getCachedLatLng(final Context context) {
public static LatLng getCachedLatLng(@NonNull final Context context) {
final Context appContext = context.getApplicationContext();
final SharedPreferences prefs = DependencyHolder.get(context).getPreferences();
if (!prefs.getBoolean(KEY_USAGE_STATISTICS, false)) return null;

View File

@ -0,0 +1,25 @@
package org.mariotaku.abstask.library;
import android.support.annotation.UiThread;
import android.support.annotation.WorkerThread;
/**
* Created by mariotaku on 16/5/25.
*/
public class ManualTaskStarter {
@UiThread
public static void invokeBeforeExecute(AbstractTask<?, ?, ?> task) {
task.invokeBeforeExecute();
}
@UiThread
public static <Result> void invokeAfterExecute(AbstractTask<?, Result, ?> task, Result result) {
task.invokeAfterExecute(result);
}
@WorkerThread
public static <Result> Result invokeExecute(AbstractTask<?, Result, ?> task) {
return task.invokeExecute();
}
}

View File

@ -25,8 +25,7 @@ import android.util.Log;
import com.bluelinelabs.logansquare.LoganSquare;
import com.fasterxml.jackson.core.TreeNode;
import org.mariotaku.restfu.callback.RawCallback;
import org.mariotaku.restfu.http.HttpResponse;
import org.mariotaku.commons.logansquare.LoganSquareMapperFinder;
import org.mariotaku.microblog.library.MicroBlogException;
import org.mariotaku.microblog.library.twitter.model.DeletionEvent;
import org.mariotaku.microblog.library.twitter.model.DirectMessage;
@ -38,7 +37,8 @@ import org.mariotaku.microblog.library.twitter.model.User;
import org.mariotaku.microblog.library.twitter.model.UserList;
import org.mariotaku.microblog.library.twitter.model.Warning;
import org.mariotaku.microblog.library.twitter.util.CRLFLineReader;
import org.mariotaku.commons.logansquare.LoganSquareMapperFinder;
import org.mariotaku.restfu.callback.RawCallback;
import org.mariotaku.restfu.http.HttpResponse;
import java.io.IOException;
import java.io.InputStreamReader;

View File

@ -25,17 +25,17 @@ import android.support.v4.util.SimpleArrayMap;
import com.bluelinelabs.logansquare.JsonMapper;
import com.fasterxml.jackson.core.JsonParseException;
import org.mariotaku.commons.logansquare.LoganSquareMapperFinder;
import org.mariotaku.microblog.library.MicroBlogException;
import org.mariotaku.microblog.library.twitter.model.ResponseCode;
import org.mariotaku.microblog.library.twitter.model.TwitterResponse;
import org.mariotaku.restfu.RestConverter;
import org.mariotaku.restfu.http.ContentType;
import org.mariotaku.restfu.http.HttpResponse;
import org.mariotaku.restfu.http.mime.Body;
import org.mariotaku.restfu.http.mime.SimpleBody;
import org.mariotaku.restfu.http.mime.StringBody;
import org.mariotaku.microblog.library.MicroBlogException;
import org.mariotaku.microblog.library.twitter.auth.OAuthToken;
import org.mariotaku.microblog.library.twitter.model.ResponseCode;
import org.mariotaku.microblog.library.twitter.model.TwitterResponse;
import org.mariotaku.commons.logansquare.LoganSquareMapperFinder;
import org.mariotaku.restfu.oauth.OAuthToken;
import java.io.IOException;
import java.lang.reflect.Type;
@ -51,7 +51,7 @@ public class TwitterConverterFactory extends RestConverter.SimpleFactory<MicroBl
static {
sResponseConverters.put(ResponseCode.class, new ResponseCode.ResponseConverter());
sResponseConverters.put(OAuthToken.class, new OAuthToken.ResponseConverter());
sResponseConverters.put(OAuthToken.class, new OAuthTokenResponseConverter());
}

View File

@ -34,7 +34,7 @@ import static org.mariotaku.twidere.annotation.PreferenceType.STRING;
public interface Constants extends TwidereConstants {
String DATABASES_NAME = "twidere.sqlite";
int DATABASES_VERSION = 145;
int DATABASES_VERSION = 151;
int MENU_GROUP_STATUS_EXTENSION = 10;
int MENU_GROUP_COMPOSE_EXTENSION = 11;

View File

@ -29,6 +29,7 @@ import android.support.annotation.NonNull;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.AsyncTaskLoader;
import android.support.v4.content.Loader;
import android.support.v7.app.AlertDialog;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
@ -42,8 +43,6 @@ import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.TextView;
import android.widget.Toast;
import com.afollestad.materialdialogs.AlertDialogWrapper;
import org.mariotaku.restfu.annotation.method.GET;
import org.mariotaku.restfu.http.HttpRequest;
import org.mariotaku.restfu.http.HttpResponse;
@ -56,8 +55,8 @@ import org.mariotaku.twidere.model.CustomAPIConfig;
import org.mariotaku.twidere.model.ParcelableCredentials;
import org.mariotaku.twidere.provider.TwidereDataStore.Accounts;
import org.mariotaku.twidere.util.JsonSerializer;
import org.mariotaku.twidere.util.ParseUtils;
import org.mariotaku.twidere.util.MicroBlogAPIFactory;
import org.mariotaku.twidere.util.ParseUtils;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper;
@ -67,9 +66,6 @@ import java.util.List;
import javax.inject.Inject;
import static org.mariotaku.twidere.util.Utils.getNonEmptyString;
import static org.mariotaku.twidere.util.Utils.trim;
public class APIEditorActivity extends BaseActivity implements OnCheckedChangeListener,
OnClickListener, CompoundButton.OnCheckedChangeListener {
@ -212,12 +208,12 @@ public class APIEditorActivity extends BaseActivity implements OnCheckedChangeLi
String consumerKey, consumerSecret;
final SharedPreferences pref = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
final String prefApiUrlFormat = getNonEmptyString(pref, KEY_API_URL_FORMAT, DEFAULT_TWITTER_API_URL_FORMAT);
final String prefApiUrlFormat = Utils.getNonEmptyString(pref, KEY_API_URL_FORMAT, DEFAULT_TWITTER_API_URL_FORMAT);
final int prefAuthType = pref.getInt(KEY_AUTH_TYPE, ParcelableCredentials.AuthType.OAUTH);
final boolean prefSameOAuthSigningUrl = pref.getBoolean(KEY_SAME_OAUTH_SIGNING_URL, false);
final boolean prefNoVersionSuffix = pref.getBoolean(KEY_NO_VERSION_SUFFIX, false);
final String prefConsumerKey = getNonEmptyString(pref, KEY_CONSUMER_KEY, TWITTER_CONSUMER_KEY);
final String prefConsumerSecret = getNonEmptyString(pref, KEY_CONSUMER_SECRET, TWITTER_CONSUMER_SECRET);
final String prefConsumerKey = Utils.getNonEmptyString(pref, KEY_CONSUMER_KEY, TWITTER_CONSUMER_KEY);
final String prefConsumerSecret = Utils.getNonEmptyString(pref, KEY_CONSUMER_SECRET, TWITTER_CONSUMER_SECRET);
final Bundle bundle;
if (savedInstanceState != null) {
bundle = savedInstanceState;
@ -226,12 +222,12 @@ public class APIEditorActivity extends BaseActivity implements OnCheckedChangeLi
} else {
bundle = new Bundle();
}
apiUrlFormat = trim(bundle.getString(Accounts.API_URL_FORMAT, prefApiUrlFormat));
apiUrlFormat = Utils.trim(bundle.getString(Accounts.API_URL_FORMAT, prefApiUrlFormat));
authType = bundle.getInt(Accounts.AUTH_TYPE, prefAuthType);
sameOAuthSigningUrl = bundle.getBoolean(Accounts.SAME_OAUTH_SIGNING_URL, prefSameOAuthSigningUrl);
noVersionSuffix = bundle.getBoolean(Accounts.NO_VERSION_SUFFIX, prefNoVersionSuffix);
consumerKey = trim(bundle.getString(Accounts.CONSUMER_KEY, prefConsumerKey));
consumerSecret = trim(bundle.getString(Accounts.CONSUMER_SECRET, prefConsumerSecret));
consumerKey = Utils.trim(bundle.getString(Accounts.CONSUMER_KEY, prefConsumerKey));
consumerSecret = Utils.trim(bundle.getString(Accounts.CONSUMER_SECRET, prefConsumerSecret));
mEditAuthType.setOnCheckedChangeListener(this);
mEditNoVersionSuffix.setOnCheckedChangeListener(this);
@ -293,7 +289,7 @@ public class APIEditorActivity extends BaseActivity implements OnCheckedChangeLi
final Context context = getContext();
List<CustomAPIConfig> configs = CustomAPIConfig.listDefault(context);
mAdapter = new CustomAPIConfigArrayAdapter(context, configs);
final AlertDialogWrapper.Builder builder = new AlertDialogWrapper.Builder(context);
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setAdapter(mAdapter, this);
if (!BuildConfig.DEBUG) {
getLoaderManager().initLoader(0, null, this);
@ -362,14 +358,14 @@ public class APIEditorActivity extends BaseActivity implements OnCheckedChangeLi
private class CustomAPIConfigArrayAdapter extends ArrayAdapter<CustomAPIConfig> {
public CustomAPIConfigArrayAdapter(Context context, List<CustomAPIConfig> defaultItems) {
super(context, R.layout.md_listitem, defaultItems);
super(context, android.R.layout.simple_list_item_1, defaultItems);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final View view = super.getView(position, convertView, parent);
CustomAPIConfig config = getItem(position);
((TextView) view.findViewById(com.afollestad.materialdialogs.R.id.title)).setText(config.getLocalizedName(getContext()));
((TextView) view.findViewById(android.R.id.text1)).setText(config.getLocalizedName(getContext()));
return view;
}
}

View File

@ -37,19 +37,19 @@ import android.webkit.WebView;
import android.widget.Toast;
import org.attoparser.AttoParseException;
import org.mariotaku.restfu.http.Authorization;
import org.mariotaku.restfu.http.Endpoint;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.R;
import org.mariotaku.microblog.library.MicroBlogException;
import org.mariotaku.microblog.library.twitter.TwitterOAuth;
import org.mariotaku.microblog.library.twitter.auth.OAuthAuthorization;
import org.mariotaku.microblog.library.twitter.auth.OAuthToken;
import org.mariotaku.restfu.http.Authorization;
import org.mariotaku.restfu.http.Endpoint;
import org.mariotaku.restfu.oauth.OAuthAuthorization;
import org.mariotaku.restfu.oauth.OAuthToken;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.model.SingleResponse;
import org.mariotaku.twidere.provider.TwidereDataStore.Accounts;
import org.mariotaku.twidere.util.AsyncTaskUtils;
import org.mariotaku.twidere.util.OAuthPasswordAuthenticator;
import org.mariotaku.twidere.util.MicroBlogAPIFactory;
import org.mariotaku.twidere.util.OAuthPasswordAuthenticator;
import org.mariotaku.twidere.util.webkit.DefaultWebViewClient;
import java.io.IOException;

View File

@ -21,7 +21,6 @@ package org.mariotaku.twidere.activity;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ActivityNotFoundException;
import android.content.ContentResolver;
@ -52,6 +51,7 @@ import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.view.SupportMenuInflater;
import android.support.v7.widget.ActionMenuView;
import android.support.v7.widget.ActionMenuView.OnMenuItemClickListener;
@ -95,19 +95,14 @@ import android.widget.Toast;
import com.afollestad.appthemeengine.Config;
import com.afollestad.appthemeengine.customizers.ATEToolbarCustomizer;
import com.afollestad.appthemeengine.util.ATEUtil;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.github.johnpersano.supertoasts.SuperToast;
import com.github.johnpersano.supertoasts.SuperToast.Duration;
import com.github.johnpersano.supertoasts.SuperToast.OnDismissListener;
import com.twitter.Extractor;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.mariotaku.abstask.library.AbstractTask;
import org.mariotaku.abstask.library.TaskStarter;
import org.mariotaku.commons.io.StreamUtils;
import org.mariotaku.multivalueswitch.library.MultiValueSwitch;
import org.mariotaku.restfu.RestFuUtils;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.iface.IExtendedActivity;
@ -209,6 +204,13 @@ public class ComposeActivity extends BaseActivity implements OnMenuItemClickList
private SupportMenuInflater mMenuInflater;
private ItemTouchHelper mItemTouchHelper;
private final Runnable mBackTimeoutRunnable = new Runnable() {
@Override
public void run() {
mNavigateBackPressed = false;
}
};
// Views
private RecyclerView mAttachedMediaPreview;
private ActionMenuView mMenuBar;
@ -580,7 +582,7 @@ public class ComposeActivity extends BaseActivity implements OnMenuItemClickList
final Draft draft = new Draft();
draft.action_type = getDraftAction(getIntent().getAction());
draft.account_ids = mAccountsAdapter.getSelectedAccountKeys();
draft.account_keys = mAccountsAdapter.getSelectedAccountKeys();
draft.text = text;
final UpdateStatusActionExtra extra = new UpdateStatusActionExtra();
extra.setInReplyToStatus(mInReplyToStatus);
@ -892,14 +894,9 @@ public class ComposeActivity extends BaseActivity implements OnMenuItemClickList
if (ACTION_NAVIGATION_BACK.equals(action)) {
if (mEditText.length() == 0 && !mTextChanged) {
if (!mNavigateBackPressed) {
final SuperToast toast = SuperToast.create(this, getString(R.string.press_again_to_close), Duration.SHORT);
toast.setOnDismissListener(new OnDismissListener() {
@Override
public void onDismiss(View view) {
mNavigateBackPressed = false;
}
});
toast.show();
Toast.makeText(this, getString(R.string.press_again_to_close), Toast.LENGTH_SHORT).show();
mEditText.removeCallbacks(mBackTimeoutRunnable);
mEditText.postDelayed(mBackTimeoutRunnable, 2000);
} else {
onBackPressed();
}
@ -1029,7 +1026,7 @@ public class ComposeActivity extends BaseActivity implements OnMenuItemClickList
mEditText.setText(draft.text);
final int selectionEnd = mEditText.length();
mEditText.setSelection(selectionEnd);
mAccountsAdapter.setSelectedAccountIds(draft.account_ids);
mAccountsAdapter.setSelectedAccountIds(draft.account_keys);
if (draft.media != null) {
addMedia(Arrays.asList(draft.media));
}
@ -1192,15 +1189,17 @@ public class ComposeActivity extends BaseActivity implements OnMenuItemClickList
if (!status.account_key.equals(status.user_key)) {
selectionStart = mEditText.length();
}
if (status.is_retweet) {
if (status.is_retweet && !TextUtils.isEmpty(status.retweeted_by_user_screen_name)) {
mentions.add(status.retweeted_by_user_screen_name);
}
if (status.is_quote) {
if (status.is_quote && !TextUtils.isEmpty(status.quoted_user_screen_name)) {
mentions.add(status.quoted_user_screen_name);
}
if (!ArrayUtils.isEmpty(status.mentions)) {
for (ParcelableUserMention mention : status.mentions) {
if (mention.key.equals(status.account_key)) continue;
if (mention.key.equals(status.account_key) || TextUtils.isEmpty(mention.screen_name)) {
continue;
}
mentions.add(mention.screen_name);
}
mentions.addAll(mExtractor.extractMentionedScreennames(status.quoted_text_plain));
@ -1517,9 +1516,7 @@ public class ComposeActivity extends BaseActivity implements OnMenuItemClickList
private void updateTextCount() {
if (mSendTextCountView == null || mEditText == null) return;
final String textOrig = ParseUtils.parseString(mEditText.getText());
final String text = hasMedia() && textOrig != null ? mImageUploaderUsed ? Utils.getImageUploadStatus(this,
new String[]{FAKE_IMAGE_LINK}, textOrig) : textOrig + " " + FAKE_IMAGE_LINK : textOrig;
final String text = ParseUtils.parseString(mEditText.getText());
final int validatedCount = text != null ? mValidator.getTweetLength(text) : 0;
mSendTextCountView.setTextCount(validatedCount);
}
@ -1760,7 +1757,7 @@ public class ComposeActivity extends BaseActivity implements OnMenuItemClickList
is = resolver.openInputStream(source);
os = resolver.openOutputStream(destination);
if (is == null || os == null) throw new FileNotFoundException();
RestFuUtils.copyStream(is, os);
StreamUtils.copy(is, os, null, null);
if (ContentResolver.SCHEME_FILE.equals(source.getScheme()) && mDeleteSrc) {
final File file = new File(source.getPath());
if (!file.delete()) {
@ -2108,35 +2105,34 @@ public class ComposeActivity extends BaseActivity implements OnMenuItemClickList
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
MaterialDialog.Builder builder = new MaterialDialog.Builder(getContext());
builder.title(R.string.edit_description);
builder.customView(R.layout.dialog_compose_edit_alt_text, true);
builder.negativeText(android.R.string.cancel);
builder.positiveText(android.R.string.ok);
builder.neutralText(R.string.clear);
builder.onNeutral(new MaterialDialog.SingleButtonCallback() {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(R.string.edit_description);
builder.setView(R.layout.dialog_compose_edit_alt_text);
builder.setNegativeButton(android.R.string.cancel, null);
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
((ComposeActivity) getActivity()).setMediaAltText(getArguments().getInt(EXTRA_POSITION), null);
}
});
builder.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
final EditText editText = (EditText) dialog.findViewById(R.id.edit_text);
public void onClick(DialogInterface dialog, int which) {
final EditText editText = (EditText) ((Dialog) dialog).findViewById(R.id.edit_text);
((ComposeActivity) getActivity()).setMediaAltText(getArguments().getInt(EXTRA_POSITION),
ParseUtils.parseString(editText.getText()));
}
});
builder.showListener(new DialogInterface.OnShowListener() {
builder.setNeutralButton(R.string.clear, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
((ComposeActivity) getActivity()).setMediaAltText(getArguments().getInt(EXTRA_POSITION), null);
}
});
final AlertDialog dialog = builder.create();
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
MaterialDialog materialDialog = ((MaterialDialog) dialog);
Dialog materialDialog = ((Dialog) dialog);
final EditText editText = (EditText) materialDialog.findViewById(R.id.edit_text);
editText.setText(getArguments().getString(EXTRA_TEXT));
}
});
return builder.build();
return dialog;
}
}

View File

@ -24,10 +24,11 @@ import android.content.Intent;
import android.content.Intent.ShortcutIconResource;
import android.os.Bundle;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
public class CreateComposeShortcutActivity extends Activity implements Constants {
import static org.mariotaku.twidere.constant.IntentConstants.INTENT_ACTION_COMPOSE;
public class CreateComposeShortcutActivity extends Activity {
@Override
protected void onCreate(final Bundle savedInstanceState) {

View File

@ -24,11 +24,10 @@ import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.fragment.SettingsDetailsFragment;
public class HiddenSettingsActivity extends BaseActivity implements Constants {
public class HiddenSettingsActivity extends BaseActivity {
@Override
protected void onCreate(final Bundle savedInstanceState) {

View File

@ -27,7 +27,6 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.database.ContentObserver;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
@ -51,6 +50,7 @@ import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatDelegate;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.TintTypedArray;
import android.support.v7.widget.Toolbar;
import android.util.SparseIntArray;
import android.view.Gravity;
@ -111,6 +111,8 @@ import java.util.List;
public class HomeActivity extends BaseActivity implements OnClickListener, OnPageChangeListener,
SupportFragmentCallback, OnLongClickListener, DrawerLayout.DrawerListener {
private static final int[] HOME_AS_UP_ATTRS = {android.support.v7.appcompat.R.attr.homeAsUpIndicator};
private final Handler mHandler = new Handler();
private final ContentObserver mAccountChangeObserver = new AccountChangeObserver(this, mHandler);
@ -156,8 +158,8 @@ public class HomeActivity extends BaseActivity implements OnClickListener, OnPag
@Override
public Drawable getThemeUpIndicator() {
final int[] attrs = {android.support.v7.appcompat.R.attr.homeAsUpIndicator};
final TypedArray a = obtainStyledAttributes(attrs);
final TintTypedArray a = TintTypedArray.obtainStyledAttributes(
getActionBarThemedContext(), null, HOME_AS_UP_ATTRS);
final Drawable result = a.getDrawable(0);
a.recycle();
return result;
@ -988,7 +990,7 @@ public class HomeActivity extends BaseActivity implements OnClickListener, OnPag
true, ReadPositionTag.HOME_TIMELINE, accountKeys);
final long position = mReadStateManager.getPosition(tagWithAccounts);
final int count = DataStoreUtils.getStatusesCount(mContext, Statuses.CONTENT_URI,
position, Statuses.STATUS_TIMESTAMP, true, accountKeys);
spec.args, position, Statuses.STATUS_TIMESTAMP, true, accountKeys);
result.put(i, count);
publishProgress(new TabBadge(i, count));
break;

View File

@ -28,7 +28,6 @@ import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.util.KeyboardShortcutsHandler;
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutSpec;
@ -37,7 +36,7 @@ import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutSpec;
* Created by mariotaku on 15/4/20.
*/
public class KeyboardShortcutPreferenceCompatActivity extends BaseActivity implements
Constants, OnClickListener {
OnClickListener {
public static final String EXTRA_CONTEXT_TAG = "context_tag";
public static final String EXTRA_KEY_ACTION = "key_action";

View File

@ -74,6 +74,7 @@ public class LinkHandlerActivity extends BaseActivity implements SystemWindowsIn
private boolean mFinishOnly;
private int mActionBarHeight;
private CharSequence mSubtitle;
private boolean mHideOffsetNotSupported;
@Override
@ -268,8 +269,13 @@ public class LinkHandlerActivity extends BaseActivity implements SystemWindowsIn
ActionBar actionBar = getSupportActionBar();
if (fragment instanceof IToolBarSupportFragment) {
((IToolBarSupportFragment) fragment).setControlBarOffset(offset);
} else if (actionBar != null) {
actionBar.setHideOffset((int) (getControlBarHeight() * offset));
} else if (actionBar != null && !mHideOffsetNotSupported) {
try {
actionBar.setHideOffset((int) (getControlBarHeight() * offset));
} catch (UnsupportedOperationException e) {
// Some device will throw this exception
mHideOffsetNotSupported = true;
}
}
notifyControlBarOffsetChanged();
}

View File

@ -25,12 +25,11 @@ import android.content.res.Configuration;
import android.os.Bundle;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.util.StrictModeUtils;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.Utils;
public class MainActivity extends Activity implements Constants {
public class MainActivity extends Activity {
@Override
protected void onCreate(final Bundle savedInstanceState) {

View File

@ -24,6 +24,7 @@ import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
@ -72,7 +73,6 @@ import org.mariotaku.mediaviewer.library.IMediaViewerActivity;
import org.mariotaku.mediaviewer.library.MediaDownloader;
import org.mariotaku.mediaviewer.library.MediaViewerFragment;
import org.mariotaku.mediaviewer.library.subsampleimageview.SubsampleImageViewerFragment;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.iface.IExtendedActivity;
import org.mariotaku.twidere.fragment.ProgressDialogFragment;
@ -106,7 +106,7 @@ import edu.tsinghua.hotmobi.model.MediaDownloadEvent;
import pl.droidsonroids.gif.GifTextureView;
import pl.droidsonroids.gif.InputSource;
public final class MediaViewerActivity extends BaseActivity implements Constants, IExtendedActivity,
public final class MediaViewerActivity extends BaseActivity implements IExtendedActivity,
ATEToolbarCustomizer, IMediaViewerActivity {
private static final int REQUEST_SHARE_MEDIA = 201;
@ -587,8 +587,9 @@ public final class MediaViewerActivity extends BaseActivity implements Constants
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
getActivity().supportInvalidateOptionsMenu();
final FragmentActivity activity = getActivity();
if (isVisibleToUser && activity != null) {
activity.supportInvalidateOptionsMenu();
}
}
@ -1028,7 +1029,10 @@ public final class MediaViewerActivity extends BaseActivity implements Constants
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
getActivity().supportInvalidateOptionsMenu();
final FragmentActivity activity = getActivity();
if (activity != null) {
activity.supportInvalidateOptionsMenu();
}
} else if (mVideoView != null && mVideoView.isPlaying()) {
mVideoView.pause();
updatePlayerState();
@ -1044,6 +1048,12 @@ public final class MediaViewerActivity extends BaseActivity implements Constants
if (handler == null) {
handler = new Handler(getActivity().getMainLooper());
}
AudioManager am = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
// Play audio by default if ringer mode on
mPlayAudio = am.getRingerMode() == AudioManager.RINGER_MODE_NORMAL;
mVideoProgressRunnable = new VideoPlayProgressRunnable(handler, mVideoViewProgress,
mDurationLabel, mPositionLabel, mVideoView);
@ -1282,7 +1292,10 @@ public final class MediaViewerActivity extends BaseActivity implements Constants
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
getActivity().supportInvalidateOptionsMenu();
final FragmentActivity activity = getActivity();
if (activity != null) {
activity.supportInvalidateOptionsMenu();
}
}
}
}

View File

@ -33,13 +33,15 @@ import android.view.View;
import android.view.View.OnLongClickListener;
import android.widget.Toast;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.nyan.NyanDaydreamService;
import org.mariotaku.twidere.nyan.NyanSurfaceHelper;
import org.mariotaku.twidere.nyan.NyanWallpaperService;
public class NyanActivity extends Activity implements Constants, OnLongClickListener, OnSharedPreferenceChangeListener {
import static org.mariotaku.twidere.TwidereConstants.SHARED_PREFERENCES_NAME;
import static org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_LIVE_WALLPAPER_SCALE;
public class NyanActivity extends Activity implements OnLongClickListener, OnSharedPreferenceChangeListener {
private SurfaceView mSurfaceView;
private SharedPreferences mPreferences;

View File

@ -12,12 +12,11 @@ import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.AsyncTaskLoader;
import android.support.v4.content.Loader;
import android.support.v7.app.AlertDialog;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.afollestad.materialdialogs.MaterialDialog;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.ArrayAdapter;
import org.mariotaku.twidere.fragment.BaseDialogFragment;
@ -46,22 +45,22 @@ public class PlusServiceDashboardActivity extends BaseActivity {
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Context context = getContext();
mAdapter = new ProviderAdapter(context);
MaterialDialog.Builder builder = new MaterialDialog.Builder(context);
builder.title(R.string.sign_in_with_ellip);
builder.adapter(mAdapter, new MaterialDialog.ListCallback() {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.sign_in_with_ellip);
builder.setAdapter(mAdapter, new DialogInterface.OnClickListener() {
@Override
public void onSelection(MaterialDialog dialog, View itemView, int which, CharSequence text) {
public void onClick(DialogInterface dialog, int which) {
startLogin(mAdapter.getItem(which));
}
});
builder.showListener(new DialogInterface.OnShowListener() {
AlertDialog dialog = builder.create();
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
loadInfo();
}
});
return builder.build();
return dialog;
}
private void startLogin(ResolveInfo info) {

View File

@ -227,14 +227,17 @@ public class SettingsActivity extends BaseActivity implements OnItemClickListene
return mShouldNotifyChange;
}
@Override
public boolean onSupportNavigateUp() {
if (notifyUnsavedChange()) {
return true;
}
return super.onSupportNavigateUp();
}
@Override
public void onBackPressed() {
if (isTopSettings() && shouldNotifyChange()) {
final RestartConfirmDialogFragment df = new RestartConfirmDialogFragment();
df.show(getSupportFragmentManager(), "restart_confirm");
return;
}
if (notifyUnsavedChange()) return;
super.onBackPressed();
}
@ -277,6 +280,15 @@ public class SettingsActivity extends BaseActivity implements OnItemClickListene
mSlidingPaneLayout.closePane();
}
private boolean notifyUnsavedChange() {
if (isTopSettings() && shouldNotifyChange()) {
final RestartConfirmDialogFragment df = new RestartConfirmDialogFragment();
df.show(getSupportFragmentManager(), "restart_confirm");
return true;
}
return false;
}
static class EntriesAdapter extends BaseAdapter {
static final int VIEW_TYPE_PREFERENCE_ENTRY = 0;

View File

@ -36,6 +36,7 @@ import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AlertDialog;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceManager;
import android.support.v7.preference.PreferenceScreen;
@ -46,14 +47,12 @@ import android.view.ViewGroup;
import com.afollestad.appthemeengine.Config;
import com.afollestad.appthemeengine.util.ATEUtil;
import com.afollestad.materialdialogs.AlertDialogWrapper;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.SupportTabsAdapter;
import org.mariotaku.twidere.annotation.CustomTabType;
import org.mariotaku.twidere.fragment.BasePreferenceFragment;
import org.mariotaku.twidere.fragment.BaseDialogFragment;
import org.mariotaku.twidere.fragment.BasePreferenceFragment;
import org.mariotaku.twidere.fragment.BaseSupportFragment;
import org.mariotaku.twidere.fragment.DirectMessagesFragment;
import org.mariotaku.twidere.fragment.HomeTimelineFragment;
@ -79,7 +78,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class SettingsWizardActivity extends BaseActivity implements Constants {
public class SettingsWizardActivity extends BaseActivity {
public static final String WIZARD_PREFERENCE_KEY_NEXT_PAGE = "next_page";
public static final String WIZARD_PREFERENCE_KEY_USE_DEFAULTS = "use_defaults";
@ -484,7 +483,7 @@ public class SettingsWizardActivity extends BaseActivity implements Constants {
@NonNull
@Override
public Dialog onCreateDialog(final Bundle savedInstanceState) {
final AlertDialogWrapper.Builder builder = new AlertDialogWrapper.Builder(getActivity());
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(R.string.wizard_page_tabs_unchanged_message);
builder.setPositiveButton(android.R.string.ok, this);
return builder.create();

View File

@ -57,27 +57,24 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.afollestad.materialdialogs.internal.MDButton;
import com.rengwuxian.materialedittext.MaterialEditText;
import org.mariotaku.microblog.library.MicroBlog;
import org.mariotaku.microblog.library.MicroBlogException;
import org.mariotaku.microblog.library.statusnet.model.StatusNetConfig;
import org.mariotaku.microblog.library.twitter.TwitterOAuth;
import org.mariotaku.microblog.library.twitter.auth.BasicAuthorization;
import org.mariotaku.microblog.library.twitter.auth.EmptyAuthorization;
import org.mariotaku.microblog.library.twitter.model.Paging;
import org.mariotaku.microblog.library.twitter.model.User;
import org.mariotaku.restfu.http.Authorization;
import org.mariotaku.restfu.http.Endpoint;
import org.mariotaku.restfu.oauth.OAuthAuthorization;
import org.mariotaku.restfu.oauth.OAuthToken;
import org.mariotaku.sqliteqb.library.Expression;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.activity.iface.IExtendedActivity;
import org.mariotaku.microblog.library.statusnet.model.StatusNetConfig;
import org.mariotaku.microblog.library.MicroBlog;
import org.mariotaku.microblog.library.MicroBlogException;
import org.mariotaku.microblog.library.twitter.TwitterOAuth;
import org.mariotaku.microblog.library.twitter.auth.BasicAuthorization;
import org.mariotaku.microblog.library.twitter.auth.EmptyAuthorization;
import org.mariotaku.microblog.library.twitter.auth.OAuthAuthorization;
import org.mariotaku.microblog.library.twitter.auth.OAuthToken;
import org.mariotaku.microblog.library.twitter.model.Paging;
import org.mariotaku.microblog.library.twitter.model.User;
import org.mariotaku.twidere.fragment.BaseDialogFragment;
import org.mariotaku.twidere.fragment.ProgressDialogFragment;
import org.mariotaku.twidere.model.ParcelableAccount;
@ -93,6 +90,7 @@ import org.mariotaku.twidere.provider.TwidereDataStore.Accounts;
import org.mariotaku.twidere.util.AsyncTaskUtils;
import org.mariotaku.twidere.util.DataStoreUtils;
import org.mariotaku.twidere.util.JsonSerializer;
import org.mariotaku.twidere.util.MicroBlogAPIFactory;
import org.mariotaku.twidere.util.OAuthPasswordAuthenticator;
import org.mariotaku.twidere.util.OAuthPasswordAuthenticator.AuthenticationException;
import org.mariotaku.twidere.util.OAuthPasswordAuthenticator.AuthenticityTokenException;
@ -101,7 +99,6 @@ import org.mariotaku.twidere.util.OAuthPasswordAuthenticator.LoginVerificationEx
import org.mariotaku.twidere.util.OAuthPasswordAuthenticator.WrongUserPassException;
import org.mariotaku.twidere.util.ParseUtils;
import org.mariotaku.twidere.util.SharedPreferencesWrapper;
import org.mariotaku.twidere.util.MicroBlogAPIFactory;
import org.mariotaku.twidere.util.TwitterContentUtils;
import org.mariotaku.twidere.util.UserAgentUtils;
import org.mariotaku.twidere.util.Utils;
@ -741,7 +738,17 @@ public class SignInActivity extends BaseActivity implements OnClickListener, Tex
final TwitterOAuth oauth = MicroBlogAPIFactory.getInstance(activity, endpoint, auth,
TwitterOAuth.class);
final OAuthToken accessToken = oauth.getAccessToken(username, password);
final String userId = accessToken.getUserId();
String userId = accessToken.getUserId();
if (userId == null) {
// Trying to fix up userId if accessToken doesn't contain one.
auth = new OAuthAuthorization(consumerKey.getOauthToken(),
consumerKey.getOauthTokenSecret(), accessToken);
endpoint = MicroBlogAPIFactory.getOAuthRestEndpoint(apiUrlFormat, sameOAuthSigningUrl,
noVersionSuffix);
MicroBlog microBlog = MicroBlogAPIFactory.getInstance(activity, endpoint, auth,
MicroBlog.class);
userId = microBlog.verifyCredentials().getId();
}
if (userId == null) return new SignInResponse(false, false, null);
return getOAuthSignInResponse(activity, accessToken, userId,
AuthType.XAUTH);
@ -1142,28 +1149,32 @@ public class SignInActivity extends BaseActivity implements OnClickListener, Tex
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final MaterialDialog.Builder builder = new MaterialDialog.Builder(getContext());
builder.positiveText(R.string.sign_in);
builder.negativeText(android.R.string.cancel);
builder.customView(R.layout.dialog_password_sign_in, true);
builder.onPositive(new MaterialDialog.SingleButtonCallback() {
final AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setView(R.layout.dialog_password_sign_in);
builder.setPositiveButton(R.string.sign_in, new DialogInterface.OnClickListener() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
EditText editUsername = (EditText) dialog.findViewById(R.id.username);
EditText editPassword = (EditText) dialog.findViewById(R.id.password);
public void onClick(DialogInterface dialog, int which) {
AlertDialog alertDialog = (AlertDialog) dialog;
EditText editUsername = (EditText) alertDialog.findViewById(R.id.username);
EditText editPassword = (EditText) alertDialog.findViewById(R.id.password);
assert editUsername != null && editPassword != null;
SignInActivity activity = (SignInActivity) getActivity();
activity.setUsernamePassword(String.valueOf(editUsername.getText()),
String.valueOf(editPassword.getText()));
activity.doLogin();
}
});
builder.showListener(new DialogInterface.OnShowListener() {
builder.setNegativeButton(android.R.string.cancel, null);
final AlertDialog alertDialog = builder.create();
alertDialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
final MaterialDialog materialDialog = (MaterialDialog) dialog;
final AlertDialog materialDialog = (AlertDialog) dialog;
final EditText editUsername = (EditText) materialDialog.findViewById(R.id.username);
final EditText editPassword = (EditText) materialDialog.findViewById(R.id.password);
assert editUsername != null && editPassword != null;
TextWatcher textWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
@ -1172,7 +1183,7 @@ public class SignInActivity extends BaseActivity implements OnClickListener, Tex
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
MDButton button = materialDialog.getActionButton(DialogAction.POSITIVE);
Button button = materialDialog.getButton(DialogInterface.BUTTON_POSITIVE);
if (button == null) return;
button.setEnabled(editUsername.length() > 0 && editPassword.length() > 0);
}
@ -1187,7 +1198,7 @@ public class SignInActivity extends BaseActivity implements OnClickListener, Tex
editPassword.addTextChangedListener(textWatcher);
}
});
return builder.build();
return alertDialog;
}
}

View File

@ -25,11 +25,10 @@ import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.fragment.SettingsDetailsFragment;
public class UsageStatisticsActivity extends BaseActivity implements Constants {
public class UsageStatisticsActivity extends BaseActivity {
@Override
protected void onDestroy() {

View File

@ -36,10 +36,6 @@ import android.widget.ListView;
import com.squareup.otto.Subscribe;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.SimpleParcelableUserListsAdapter;
import org.mariotaku.twidere.adapter.SimpleParcelableUsersAdapter;
import org.mariotaku.twidere.adapter.UserAutoCompleteAdapter;
import org.mariotaku.microblog.library.MicroBlog;
import org.mariotaku.microblog.library.MicroBlogException;
import org.mariotaku.microblog.library.twitter.http.HttpResponseCode;
@ -47,6 +43,10 @@ import org.mariotaku.microblog.library.twitter.model.Paging;
import org.mariotaku.microblog.library.twitter.model.ResponseList;
import org.mariotaku.microblog.library.twitter.model.User;
import org.mariotaku.microblog.library.twitter.model.UserList;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.SimpleParcelableUserListsAdapter;
import org.mariotaku.twidere.adapter.SimpleParcelableUsersAdapter;
import org.mariotaku.twidere.adapter.UserAutoCompleteAdapter;
import org.mariotaku.twidere.fragment.CreateUserListDialogFragment;
import org.mariotaku.twidere.fragment.ProgressDialogFragment;
import org.mariotaku.twidere.model.ParcelableUser;
@ -57,8 +57,8 @@ import org.mariotaku.twidere.model.message.UserListCreatedEvent;
import org.mariotaku.twidere.model.util.ParcelableUserListUtils;
import org.mariotaku.twidere.model.util.ParcelableUserUtils;
import org.mariotaku.twidere.util.AsyncTaskUtils;
import org.mariotaku.twidere.util.ParseUtils;
import org.mariotaku.twidere.util.MicroBlogAPIFactory;
import org.mariotaku.twidere.util.ParseUtils;
import java.util.ArrayList;
import java.util.List;
@ -299,7 +299,7 @@ public class UserListSelectorActivity extends BaseActivity implements OnClickLis
@Override
protected SingleResponse<List<ParcelableUserList>> doInBackground(final Object... params) {
final MicroBlog twitter = MicroBlogAPIFactory.getTwitterInstance(mActivity, mAccountKey, false);
final MicroBlog twitter = MicroBlogAPIFactory.getInstance(mActivity, mAccountKey, false);
if (twitter == null) return SingleResponse.getInstance();
try {
final ResponseList<UserList> lists = twitter.getUserLists(mScreenName, true);
@ -363,7 +363,7 @@ public class UserListSelectorActivity extends BaseActivity implements OnClickLis
@Override
protected SingleResponse<List<ParcelableUser>> doInBackground(final Object... params) {
final MicroBlog twitter = MicroBlogAPIFactory.getTwitterInstance(mActivity, mAccountKey, false);
final MicroBlog twitter = MicroBlogAPIFactory.getInstance(mActivity, mAccountKey, false);
if (twitter == null) return SingleResponse.getInstance();
try {
final Paging paging = new Paging();

View File

@ -36,7 +36,7 @@ public interface IControlBarActivity {
final class ControlBarShowHideHelper {
private static final long DURATION = 200l;
private static final long DURATION = 200L;
private final IControlBarActivity mActivity;
private int mControlAnimationDirection;

View File

@ -27,7 +27,6 @@ import android.widget.CompoundButton;
import com.mobeta.android.dslv.SimpleDragSortCursorAdapter;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.iface.IBaseAdapter;
import org.mariotaku.twidere.model.ParcelableAccount;
@ -43,7 +42,7 @@ import org.mariotaku.twidere.view.holder.AccountViewHolder;
import javax.inject.Inject;
public class AccountsAdapter extends SimpleDragSortCursorAdapter implements Constants, IBaseAdapter {
public class AccountsAdapter extends SimpleDragSortCursorAdapter implements IBaseAdapter {
@Inject
MediaLoaderWrapper mImageLoader;

View File

@ -27,7 +27,8 @@ import android.widget.ImageView;
import android.widget.TextView;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.fragment.MessagesConversationFragment;
import org.mariotaku.twidere.TwidereConstants;
import org.mariotaku.twidere.constant.SharedPreferenceConstants;
import org.mariotaku.twidere.model.ParcelableCredentials;
import org.mariotaku.twidere.model.UserKey;
import org.mariotaku.twidere.util.MediaLoaderWrapper;
@ -53,8 +54,8 @@ public class AccountsSpinnerAdapter extends ArrayAdapter<ParcelableCredentials>
super(context, itemViewResource);
GeneralComponentHelper.build(context).inject(this);
mContext = context;
mDisplayProfileImage = context.getSharedPreferences(MessagesConversationFragment.SHARED_PREFERENCES_NAME,
Context.MODE_PRIVATE).getBoolean(MessagesConversationFragment.KEY_DISPLAY_PROFILE_IMAGE, true);
mDisplayProfileImage = context.getSharedPreferences(TwidereConstants.SHARED_PREFERENCES_NAME,
Context.MODE_PRIVATE).getBoolean(SharedPreferenceConstants.KEY_DISPLAY_PROFILE_IMAGE, true);
}
public AccountsSpinnerAdapter(final Context context, final Collection<ParcelableCredentials> accounts) {

View File

@ -23,6 +23,7 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.adapter.iface.IBaseAdapter;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.util.MediaLoaderWrapper;
@ -38,7 +39,8 @@ import java.util.Collection;
import javax.inject.Inject;
public class BaseArrayAdapter<T> extends ArrayAdapter<T> implements IBaseAdapter, OnSharedPreferenceChangeListener {
public class BaseArrayAdapter<T> extends ArrayAdapter<T> implements Constants, IBaseAdapter,
OnSharedPreferenceChangeListener {
private final TwidereLinkify mLinkify;
@Inject

View File

@ -97,4 +97,11 @@ public abstract class BaseRecyclerViewAdapter<VH extends RecyclerView.ViewHolder
public final BidiFormatter getBidiFormatter() {
return mBidiFormatter;
}
public int findPositionByItemId(long itemId) {
for (int i = 0, j = getItemCount(); i < j; i++) {
if (getItemId(i) == itemId) return i;
}
return RecyclerView.NO_POSITION;
}
}

View File

@ -39,11 +39,9 @@ import org.mariotaku.twidere.util.MediaLoaderWrapper;
import org.mariotaku.twidere.util.SharedPreferencesWrapper;
import org.mariotaku.twidere.util.UserColorNameManager;
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper;
import org.mariotaku.twidere.view.ProfileImageView;
import javax.inject.Inject;
public class ComposeAutoCompleteAdapter extends SimpleCursorAdapter implements Constants {
private static final String[] FROM = new String[0];

View File

@ -27,14 +27,12 @@ import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.model.Draft;
import org.mariotaku.twidere.model.DraftCursorIndices;
import org.mariotaku.twidere.model.ParcelableMedia;
import org.mariotaku.twidere.model.ParcelableMediaUpdate;
import org.mariotaku.twidere.model.util.ParcelableMediaUtils;
import org.mariotaku.twidere.model.util.UserKeyUtils;
import org.mariotaku.twidere.util.DataStoreUtils;
import org.mariotaku.twidere.util.JsonSerializer;
import org.mariotaku.twidere.util.MediaLoaderWrapper;
@ -47,7 +45,9 @@ import org.mariotaku.twidere.view.holder.DraftViewHolder;
import javax.inject.Inject;
public class DraftsAdapter extends SimpleCursorAdapter implements Constants {
import static org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_MEDIA_PREVIEW_STYLE;
public class DraftsAdapter extends SimpleCursorAdapter {
@Inject
MediaLoaderWrapper mImageLoader;
@ -69,7 +69,7 @@ public class DraftsAdapter extends SimpleCursorAdapter implements Constants {
@Override
public void bindView(final View view, final Context context, final Cursor cursor) {
final DraftViewHolder holder = (DraftViewHolder) view.getTag();
final long[] accountIds = TwidereArrayUtils.parseLongArray(cursor.getString(mIndices.account_ids), ',');
final long[] accountIds = TwidereArrayUtils.parseLongArray(cursor.getString(mIndices.account_keys), ',');
final String text = cursor.getString(mIndices.text);
final ParcelableMediaUpdate[] mediaUpdates = JsonSerializer.parseArray(cursor.getString(mIndices.media),
ParcelableMediaUpdate.class);

View File

@ -24,7 +24,6 @@ import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.loader.ExtensionsListLoader.ExtensionInfo;
import org.mariotaku.twidere.util.PermissionsManager;
@ -32,7 +31,7 @@ import org.mariotaku.twidere.view.holder.CheckableTwoLineWithIconViewHolder;
import java.util.List;
public class ExtensionsAdapter extends ArrayAdapter<ExtensionInfo> implements Constants {
public class ExtensionsAdapter extends ArrayAdapter<ExtensionInfo> {
private final PermissionsManager mPermissionsManager;

View File

@ -2,7 +2,6 @@ package org.mariotaku.twidere.adapter;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.CardView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -17,8 +16,8 @@ import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder;
*/
public class ListParcelableStatusesAdapter extends ParcelableStatusesAdapter {
public ListParcelableStatusesAdapter(Context context, boolean compact) {
super(context, compact);
public ListParcelableStatusesAdapter(Context context) {
super(context);
}
@Override
@ -28,24 +27,13 @@ public class ListParcelableStatusesAdapter extends ParcelableStatusesAdapter {
@NonNull
@Override
protected IStatusViewHolder onCreateStatusViewHolder(ViewGroup parent, boolean compact) {
return createStatusViewHolder(this, getInflater(), parent, compact,
getCardBackgroundColor());
protected IStatusViewHolder onCreateStatusViewHolder(ViewGroup parent) {
return createStatusViewHolder(this, getInflater(), parent);
}
public static StatusViewHolder createStatusViewHolder(IStatusesAdapter<?> adapter,
LayoutInflater inflater, ViewGroup parent,
boolean compact, int cardBackgroundColor) {
final View view;
if (compact) {
view = inflater.inflate(R.layout.card_item_status_compact, parent, false);
final View itemContent = view.findViewById(R.id.item_content);
itemContent.setBackgroundColor(cardBackgroundColor);
} else {
view = inflater.inflate(R.layout.card_item_status, parent, false);
final CardView cardView = (CardView) view.findViewById(R.id.card);
cardView.setCardBackgroundColor(cardBackgroundColor);
}
LayoutInflater inflater, ViewGroup parent) {
final View view = inflater.inflate(R.layout.card_item_status_compact, parent, false);
final StatusViewHolder holder = new StatusViewHolder(adapter, view);
holder.setOnClickListeners();
holder.setupViewOptions();

View File

@ -46,8 +46,8 @@ import org.mariotaku.twidere.view.holder.MessageViewHolder;
import java.lang.ref.WeakReference;
public class MessageConversationAdapter extends BaseRecyclerViewAdapter<ViewHolder> implements Constants,
IDirectMessagesAdapter {
public class MessageConversationAdapter extends BaseRecyclerViewAdapter<ViewHolder> implements
Constants, IDirectMessagesAdapter {
private static final int ITEM_VIEW_TYPE_MESSAGE_OUTGOING = 1;
private static final int ITEM_VIEW_TYPE_MESSAGE_INCOMING = 2;

View File

@ -41,8 +41,8 @@ import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder;
import org.mariotaku.twidere.view.holder.MessageEntryViewHolder;
public class MessageEntriesAdapter extends LoadMoreSupportAdapter<ViewHolder> implements Constants,
IContentCardAdapter, OnClickListener, OnReadStateChangeListener {
public class MessageEntriesAdapter extends LoadMoreSupportAdapter<ViewHolder> implements
Constants, IContentCardAdapter, OnClickListener, OnReadStateChangeListener {
public static final int ITEM_VIEW_TYPE_MESSAGE = 0;
public static final int ITEM_VIEW_TYPE_LOAD_INDICATOR = 1;

View File

@ -23,7 +23,6 @@ import android.content.Context;
import android.database.Cursor;
import android.support.annotation.Nullable;
import android.support.v4.widget.Space;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
@ -32,10 +31,9 @@ import android.widget.TextView;
import org.apache.commons.lang3.ArrayUtils;
import org.mariotaku.library.objectcursor.ObjectCursor;
import org.mariotaku.twidere.Constants;
import org.mariotaku.microblog.library.twitter.model.Activity;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.iface.IActivitiesAdapter;
import org.mariotaku.microblog.library.twitter.model.Activity;
import org.mariotaku.twidere.fragment.CursorActivitiesFragment;
import org.mariotaku.twidere.fragment.UserFragment;
import org.mariotaku.twidere.model.ParcelableActivity;
@ -59,11 +57,13 @@ import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder;
import java.lang.ref.WeakReference;
import java.util.List;
import static org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_NEW_DOCUMENT_API;
/**
* Created by mariotaku on 15/1/3.
*/
public class ParcelableActivitiesAdapter extends LoadMoreSupportAdapter<RecyclerView.ViewHolder>
implements Constants, IActivitiesAdapter<List<ParcelableActivity>> {
implements IActivitiesAdapter<List<ParcelableActivity>> {
public static final int ITEM_VIEW_TYPE_STUB = 0;
public static final int ITEM_VIEW_TYPE_GAP = 1;
@ -74,7 +74,6 @@ public class ParcelableActivitiesAdapter extends LoadMoreSupportAdapter<Recycler
private final LayoutInflater mInflater;
private final MediaLoadingHandler mLoadingHandler;
private final int mCardBackgroundColor;
private final boolean mCompactCards;
private final DummyItemAdapter mStatusAdapterDelegate;
private final EventListener mEventListener;
private List<ParcelableActivity> mData;
@ -84,7 +83,7 @@ public class ParcelableActivitiesAdapter extends LoadMoreSupportAdapter<Recycler
private boolean mFollowingOnly;
private boolean mMentionsOnly;
public ParcelableActivitiesAdapter(Context context, boolean compact, boolean byFriends) {
public ParcelableActivitiesAdapter(Context context, boolean byFriends) {
super(context);
mStatusAdapterDelegate = new DummyItemAdapter(context,
new TwidereLinkify(new OnLinkClickHandler(context, null, mPreferences)), this);
@ -94,7 +93,6 @@ public class ParcelableActivitiesAdapter extends LoadMoreSupportAdapter<Recycler
mInflater = LayoutInflater.from(context);
mLoadingHandler = new MediaLoadingHandler(R.id.media_preview_progress);
mEventListener = new EventListener(this);
mCompactCards = compact;
mStatusAdapterDelegate.updateOptions();
mIsByFriends = byFriends;
}
@ -253,30 +251,15 @@ public class ParcelableActivitiesAdapter extends LoadMoreSupportAdapter<Recycler
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case ITEM_VIEW_TYPE_STATUS: {
final View view;
if (mCompactCards) {
view = mInflater.inflate(R.layout.card_item_status_compact, parent, false);
final View itemContent = view.findViewById(R.id.item_content);
itemContent.setBackgroundColor(mCardBackgroundColor);
} else {
view = mInflater.inflate(R.layout.card_item_status, parent, false);
final CardView cardView = (CardView) view.findViewById(R.id.card);
cardView.setCardBackgroundColor(mCardBackgroundColor);
}
final StatusViewHolder holder = new StatusViewHolder(mStatusAdapterDelegate, view);
holder.setupViewOptions();
final StatusViewHolder holder = ListParcelableStatusesAdapter.createStatusViewHolder(mStatusAdapterDelegate,
mInflater, parent);
holder.setStatusClickListener(mEventListener);
return holder;
}
case ITEM_VIEW_TYPE_TITLE_SUMMARY: {
final View view;
if (mCompactCards) {
view = mInflater.inflate(R.layout.card_item_activity_summary_compact, parent, false);
} else {
view = mInflater.inflate(R.layout.card_item_activity_summary, parent, false);
}
final View view = mInflater.inflate(R.layout.card_item_activity_summary_compact, parent, false);
final ActivityTitleSummaryViewHolder holder = new ActivityTitleSummaryViewHolder(this,
view, mCompactCards);
view);
holder.setOnClickListeners();
holder.setTextSize(getTextSize());
return holder;

View File

@ -38,7 +38,6 @@ import org.mariotaku.twidere.model.ParcelableStatusCursorIndices;
import org.mariotaku.twidere.model.UserKey;
import org.mariotaku.twidere.util.MediaLoadingHandler;
import org.mariotaku.twidere.util.StatusAdapterLinkClickHandler;
import org.mariotaku.twidere.util.ThemeUtils;
import org.mariotaku.twidere.util.TwidereLinkify;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.view.CardMediaContainer;
@ -60,7 +59,6 @@ public abstract class ParcelableStatusesAdapter extends LoadMoreSupportAdapter<R
private final LayoutInflater mInflater;
private final MediaLoadingHandler mLoadingHandler;
private final TwidereLinkify mLinkify;
private final int mCardBackgroundColor;
private final int mTextSize;
@ShapedImageView.ShapeStyle
private final int mProfileImageStyle;
@ -68,7 +66,6 @@ public abstract class ParcelableStatusesAdapter extends LoadMoreSupportAdapter<R
private final int mMediaPreviewStyle;
@TwidereLinkify.HighlightStyle
private final int mLinkHighlightingStyle;
private final boolean mCompactCards;
private final boolean mNameFirst;
private final boolean mDisplayMediaPreview;
private final boolean mDisplayProfileImage;
@ -81,17 +78,14 @@ public abstract class ParcelableStatusesAdapter extends LoadMoreSupportAdapter<R
private boolean mShowInReplyTo;
private boolean mShowAccountsColor;
private List<ParcelableStatus> mData;
private int mShowingActionCardPosition = RecyclerView.NO_POSITION;
private long mShowingActionCardId = RecyclerView.NO_ID;
private boolean mLastItemFiltered;
public ParcelableStatusesAdapter(Context context, boolean compact) {
public ParcelableStatusesAdapter(Context context) {
super(context);
mCardBackgroundColor = ThemeUtils.getCardBackgroundColor(context, ThemeUtils.getThemeBackgroundOption(context),
ThemeUtils.getUserThemeBackgroundAlpha(context));
mInflater = LayoutInflater.from(context);
mLoadingHandler = new MediaLoadingHandler(getProgressViewIds());
mTextSize = mPreferences.getInt(KEY_TEXT_SIZE, context.getResources().getInteger(R.integer.default_text_size));
mCompactCards = compact;
mProfileImageStyle = Utils.getProfileImageStyle(mPreferences.getString(KEY_PROFILE_IMAGE_STYLE, null));
mMediaPreviewStyle = Utils.getMediaPreviewStyle(mPreferences.getString(KEY_MEDIA_PREVIEW_STYLE, null));
mLinkHighlightingStyle = Utils.getLinkHighlightingStyleInt(mPreferences.getString(KEY_LINK_HIGHLIGHT_OPTION, null));
@ -302,15 +296,19 @@ public abstract class ParcelableStatusesAdapter extends LoadMoreSupportAdapter<R
@Override
public boolean isCardActionsShown(int position) {
if (position == RecyclerView.NO_POSITION) return mShowCardActions;
return mShowCardActions || mShowingActionCardPosition == position;
return mShowCardActions || mShowingActionCardId == getItemId(position);
}
@Override
public void showCardActions(int position) {
if (mShowingActionCardPosition != RecyclerView.NO_POSITION) {
notifyItemChanged(mShowingActionCardPosition);
if (mShowingActionCardId != RecyclerView.NO_ID) {
final int pos = findPositionByItemId(mShowingActionCardId);
if (pos != RecyclerView.NO_POSITION) {
notifyItemChanged(pos);
}
}
mShowingActionCardPosition = position;
mShowingActionCardId = getItemId(position);
if (position != RecyclerView.NO_POSITION) {
notifyItemChanged(position);
}
@ -344,7 +342,7 @@ public abstract class ParcelableStatusesAdapter extends LoadMoreSupportAdapter<R
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case ITEM_VIEW_TYPE_STATUS: {
return (RecyclerView.ViewHolder) onCreateStatusViewHolder(parent, mCompactCards);
return (RecyclerView.ViewHolder) onCreateStatusViewHolder(parent);
}
case ITEM_VIEW_TYPE_GAP: {
final View view = mInflater.inflate(R.layout.card_item_gap, parent, false);
@ -365,12 +363,8 @@ public abstract class ParcelableStatusesAdapter extends LoadMoreSupportAdapter<R
return mInflater;
}
protected int getCardBackgroundColor() {
return mCardBackgroundColor;
}
@NonNull
protected abstract IStatusViewHolder onCreateStatusViewHolder(ViewGroup parent, boolean compact);
protected abstract IStatusViewHolder onCreateStatusViewHolder(ViewGroup parent);
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

View File

@ -26,12 +26,11 @@ import android.support.v4.widget.SimpleCursorAdapter;
import android.view.View;
import android.widget.TextView;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.app.TwidereApplication;
import org.mariotaku.twidere.provider.TwidereDataStore.CachedStatuses;
import org.mariotaku.twidere.util.HtmlEscapeHelper;
public class SourceAutoCompleteAdapter extends SimpleCursorAdapter implements Constants {
public class SourceAutoCompleteAdapter extends SimpleCursorAdapter {
private static final String[] COLUMNS = new String[]{CachedStatuses._ID, CachedStatuses.SOURCE};
private static final String[] FROM = new String[0];

View File

@ -46,8 +46,8 @@ import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder;
*/
public class StaggeredGridParcelableStatusesAdapter extends ParcelableStatusesAdapter {
public StaggeredGridParcelableStatusesAdapter(Context context, boolean compact) {
super(context, compact);
public StaggeredGridParcelableStatusesAdapter(Context context) {
super(context);
}
@Override
@ -57,7 +57,7 @@ public class StaggeredGridParcelableStatusesAdapter extends ParcelableStatusesAd
@NonNull
@Override
protected IStatusViewHolder onCreateStatusViewHolder(ViewGroup parent, boolean compact) {
protected IStatusViewHolder onCreateStatusViewHolder(ViewGroup parent) {
final View view = getInflater().inflate(R.layout.adapter_item_media_status, parent, false);
final MediaStatusViewHolder holder = new MediaStatusViewHolder(this, view);
holder.setOnClickListeners();

View File

@ -28,7 +28,6 @@ import android.support.v4.app.FragmentManager;
import android.view.View;
import android.view.ViewGroup;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface;
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback;
import org.mariotaku.twidere.model.SupportTabSpec;
@ -43,8 +42,7 @@ import java.util.List;
import static org.mariotaku.twidere.util.CustomTabUtils.getTabIconDrawable;
import static org.mariotaku.twidere.util.Utils.announceForAccessibilityCompat;
public class SupportTabsAdapter extends SupportFixedFragmentStatePagerAdapter implements TabProvider, TabListener,
Constants {
public class SupportTabsAdapter extends SupportFixedFragmentStatePagerAdapter implements TabProvider, TabListener {
private static final String EXTRA_ADAPTER_POSITION = "adapter_position";

Some files were not shown because too many files have changed in this diff Show More