This commit is contained in:
Mariotaku Lee 2017-11-30 14:24:49 +08:00
parent c2d4a44632
commit 6168d07119
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
11 changed files with 189 additions and 114 deletions

View File

@ -16,8 +16,8 @@ allprojects {
ext {
projectGroupId = 'org.mariotaku.twidere'
projectVersionCode = 397
projectVersionName = '3.7.3'
projectVersionCode = 398
projectVersionName = '4.0.0-SNAPSHOT'
globalCompileSdkVersion = 27
globalBuildToolsVersion = '27.0.1'

View File

@ -64,11 +64,6 @@ public interface TwidereConstants extends SharedPreferenceConstants, IntentConst
String ETAG_MASTODON_APPS_PREFERENCES_NAME = "mastodon_apps";
String ACCOUNT_PREFERENCES_NAME_PREFIX = "account_preferences_";
String TWITTER_CONSUMER_KEY = "0WEJk1x6AlgtjGRhyABXw";
String TWITTER_CONSUMER_SECRET = "gWXNqEFhO3fMkAqoIKpTdjK0MOJs68xnOky0FRdDTP8";
String DEFAULT_TWITTER_API_URL_FORMAT = "https://[DOMAIN.]twitter.com/";
String SCHEME_HTTP = "http";
String SCHEME_HTTPS = "https";
String SCHEME_CONTENT = ContentResolver.SCHEME_CONTENT;

View File

@ -25,10 +25,6 @@ import com.bluelinelabs.logansquare.annotation.JsonField;
import com.bluelinelabs.logansquare.annotation.JsonObject;
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
/**
* Created by mariotaku on 2016/12/2.
*/
@ParcelablePlease
@JsonObject
public class OAuthCredentials extends Credentials implements Parcelable {

View File

@ -21,7 +21,13 @@
"no_version_suffix": true,
"consumer_key": "86d1146dda1d21d59351008a1d1058fd",
"consumer_secret": "c00f4b83dbfc52e2ed78a21d4edfc3cc",
"sign_up_url": "https://fanfou.com/register"
"sign_up_url": "https://fanfou.com/register",
"overlays": {
"398": {
"api_url_format": "https://api.fanfou.com/",
"same_oauth_url": false
}
}
},
{
"name": "Quitter.se",

View File

@ -115,4 +115,8 @@ public interface Constants extends TwidereConstants {
// Intent constants
String EXTRA_PRODUCT_TYPE = "product_type";
String DEFAULT_TWITTER_API_URL_FORMAT = "https://[DOMAIN.]twitter.com/";
String TWITTER_CONSUMER_KEY = "0WEJk1x6AlgtjGRhyABXw";
String TWITTER_CONSUMER_SECRET = "gWXNqEFhO3fMkAqoIKpTdjK0MOJs68xnOky0FRdDTP8";
}

View File

@ -10,8 +10,11 @@ import android.support.annotation.Nullable;
import com.bluelinelabs.logansquare.annotation.JsonField;
import com.bluelinelabs.logansquare.annotation.JsonObject;
import com.bluelinelabs.logansquare.annotation.OnJsonParseComplete;
import com.hannesdorfmann.parcelableplease.annotation.ParcelableNoThanks;
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.annotation.AccountType;
import org.mariotaku.twidere.model.account.cred.Credentials;
@ -21,18 +24,28 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static org.mariotaku.twidere.TwidereConstants.DEFAULT_TWITTER_API_URL_FORMAT;
import static org.mariotaku.twidere.TwidereConstants.TWITTER_CONSUMER_KEY;
import static org.mariotaku.twidere.TwidereConstants.TWITTER_CONSUMER_SECRET;
import static org.mariotaku.twidere.Constants.DEFAULT_TWITTER_API_URL_FORMAT;
import static org.mariotaku.twidere.Constants.TWITTER_CONSUMER_KEY;
import static org.mariotaku.twidere.Constants.TWITTER_CONSUMER_SECRET;
/**
* Created by mariotaku on 16/3/12.
*/
@ParcelablePlease
@JsonObject
public final class CustomAPIConfig implements Parcelable {
public static final Creator<CustomAPIConfig> CREATOR = new Creator<CustomAPIConfig>() {
public CustomAPIConfig createFromParcel(Parcel source) {
CustomAPIConfig target = new CustomAPIConfig();
CustomAPIConfigParcelablePlease.readFromParcel(target, source);
return target;
}
public CustomAPIConfig[] newArray(int size) {
return new CustomAPIConfig[size];
}
};
@JsonField(name = "name")
String name;
@AccountType
@ -60,8 +73,25 @@ public final class CustomAPIConfig implements Parcelable {
@Nullable
@JsonField(name = "sign_up_url")
String signUpUrl;
@Nullable
@JsonField(name = "overlays")
@ParcelableNoThanks
Map<String, CustomAPIConfig> overlays;
boolean isDefault;
@ParcelableNoThanks
private boolean apiUrlFormatChanged;
@ParcelableNoThanks
private boolean credentialsTypeChanged;
@ParcelableNoThanks
private boolean sameOAuthUrlChanged;
@ParcelableNoThanks
private boolean noVersionSuffixChanged;
@ParcelableNoThanks
private boolean consumerKeyChanged;
@ParcelableNoThanks
private boolean consumerSecretChanged;
@ParcelableNoThanks
private boolean signUpUrlChanged;
public CustomAPIConfig() {
}
@ -79,6 +109,31 @@ public final class CustomAPIConfig implements Parcelable {
this.consumerSecret = consumerSecret;
}
@NonNull
public static List<CustomAPIConfig> listDefault(@NonNull Context context) {
final AssetManager assets = context.getAssets();
try (InputStream is = assets.open("data/default_api_configs.json")) {
return JsonSerializer.parseList(is, CustomAPIConfig.class);
} catch (IOException e) {
return listBuiltin(context);
}
}
public static CustomAPIConfig builtin(@NonNull Context context) {
return new CustomAPIConfig(context.getString(R.string.provider_default), AccountType.TWITTER,
DEFAULT_TWITTER_API_URL_FORMAT, Credentials.Type.OAUTH, true, false,
TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET);
}
public static CustomAPIConfig mastodon(@NonNull Context context) {
return new CustomAPIConfig(context.getString(R.string.provider_mastodon), AccountType.MASTODON,
null, Credentials.Type.OAUTH2, true, true, null, null);
}
public static List<CustomAPIConfig> listBuiltin(@NonNull Context context) {
return Collections.singletonList(builtin(context));
}
@Nullable
public String getType() {
return type;
@ -115,50 +170,56 @@ public final class CustomAPIConfig implements Parcelable {
return apiUrlFormat;
}
public void setApiUrlFormat(@Nullable String apiUrlFormat) {
this.apiUrlFormat = apiUrlFormat;
apiUrlFormatChanged = true;
}
public String getCredentialsType() {
return credentialsType;
}
public void setCredentialsType(String credentialsType) {
this.credentialsType = credentialsType;
credentialsTypeChanged = true;
}
public boolean isSameOAuthUrl() {
return sameOAuthUrl;
}
public void setSameOAuthUrl(boolean sameOAuthUrl) {
this.sameOAuthUrl = sameOAuthUrl;
sameOAuthUrlChanged = true;
}
public boolean isNoVersionSuffix() {
return noVersionSuffix;
}
public void setNoVersionSuffix(boolean noVersionSuffix) {
this.noVersionSuffix = noVersionSuffix;
noVersionSuffixChanged = true;
}
@Nullable
public String getConsumerKey() {
return consumerKey;
}
public void setConsumerKey(@Nullable String consumerKey) {
this.consumerKey = consumerKey;
consumerKeyChanged = true;
}
@Nullable
public String getConsumerSecret() {
return consumerSecret;
}
public void setApiUrlFormat(@Nullable String apiUrlFormat) {
this.apiUrlFormat = apiUrlFormat;
}
public void setConsumerKey(@Nullable String consumerKey) {
this.consumerKey = consumerKey;
}
public void setConsumerSecret(@Nullable String consumerSecret) {
this.consumerSecret = consumerSecret;
}
public void setCredentialsType(String credentialsType) {
this.credentialsType = credentialsType;
}
public void setSameOAuthUrl(boolean sameOAuthUrl) {
this.sameOAuthUrl = sameOAuthUrl;
}
public void setNoVersionSuffix(boolean noVersionSuffix) {
this.noVersionSuffix = noVersionSuffix;
consumerSecretChanged = true;
}
@Nullable
@ -168,6 +229,7 @@ public final class CustomAPIConfig implements Parcelable {
public void setSignUpUrl(@Nullable String signUpUrl) {
this.signUpUrl = signUpUrl;
signUpUrlChanged = true;
}
public boolean isDefault() {
@ -220,40 +282,50 @@ public final class CustomAPIConfig implements Parcelable {
return result;
}
public static final Creator<CustomAPIConfig> CREATOR = new Creator<CustomAPIConfig>() {
public CustomAPIConfig createFromParcel(Parcel source) {
CustomAPIConfig target = new CustomAPIConfig();
CustomAPIConfigParcelablePlease.readFromParcel(target, source);
return target;
}
public CustomAPIConfig[] newArray(int size) {
return new CustomAPIConfig[size];
}
};
@NonNull
public static List<CustomAPIConfig> listDefault(@NonNull Context context) {
final AssetManager assets = context.getAssets();
try (InputStream is = assets.open("data/default_api_configs.json")) {
return JsonSerializer.parseList(is, CustomAPIConfig.class);
} catch (IOException e) {
return listBuiltin(context);
@OnJsonParseComplete
void onJsonParseComplete() {
if (overlays != null) {
String bestKey = null;
int maxMatchingVersion = 0;
for (String key : overlays.keySet()) {
try {
int version = Integer.parseInt(key);
if (version <= BuildConfig.VERSION_CODE && version > maxMatchingVersion) {
bestKey = key;
maxMatchingVersion = version;
}
} catch (NumberFormatException e) {
// Ignore
}
}
if (bestKey != null) {
CustomAPIConfig overlay = overlays.get(bestKey);
applyOverlay(overlay);
}
}
}
public static CustomAPIConfig builtin(@NonNull Context context) {
return new CustomAPIConfig(context.getString(R.string.provider_default), AccountType.TWITTER,
DEFAULT_TWITTER_API_URL_FORMAT, Credentials.Type.OAUTH, true, false,
TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET);
}
public static CustomAPIConfig mastodon(@NonNull Context context) {
return new CustomAPIConfig(context.getString(R.string.provider_mastodon), AccountType.MASTODON,
null, Credentials.Type.OAUTH2, true, true, null, null);
}
public static List<CustomAPIConfig> listBuiltin(@NonNull Context context) {
return Collections.singletonList(builtin(context));
private void applyOverlay(CustomAPIConfig overlay) {
if (overlay.apiUrlFormatChanged) {
apiUrlFormat = overlay.apiUrlFormat;
}
if (overlay.credentialsTypeChanged) {
credentialsType = overlay.credentialsType;
}
if (overlay.sameOAuthUrlChanged) {
sameOAuthUrl = overlay.sameOAuthUrl;
}
if (overlay.noVersionSuffixChanged) {
noVersionSuffix = overlay.noVersionSuffix;
}
if (overlay.consumerKeyChanged) {
consumerKey = overlay.consumerKey;
}
if (overlay.consumerSecretChanged) {
consumerSecret = overlay.consumerSecret;
}
if (overlay.signUpUrlChanged) {
signUpUrl = overlay.signUpUrl;
}
}
}

View File

@ -18,7 +18,9 @@ import org.mariotaku.restfu.http.MultiValueMap;
import org.mariotaku.restfu.http.SimpleValueMap;
import org.mariotaku.restfu.oauth.OAuthEndpoint;
import org.mariotaku.restfu.oauth.OAuthToken;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.TwidereConstants;
import org.mariotaku.twidere.annotation.AccountType;
import org.mariotaku.twidere.extension.model.AccountExtensionsKt;
import org.mariotaku.twidere.extension.model.CredentialsExtensionsKt;
import org.mariotaku.twidere.model.ConsumerKeyType;
@ -106,7 +108,7 @@ public class MicroBlogAPIFactory implements TwidereConstants {
}
// In case someone set invalid base url
if (HttpUrl.parse(baseUrl) == null) {
return getApiBaseUrl(DEFAULT_TWITTER_API_URL_FORMAT, domain);
return getApiBaseUrl(Constants.DEFAULT_TWITTER_API_URL_FORMAT, domain);
}
return baseUrl;
}
@ -190,25 +192,27 @@ public class MicroBlogAPIFactory implements TwidereConstants {
}
}
public static Endpoint getOAuthRestEndpoint(@NonNull String apiUrlFormat, boolean sameOAuthSigningUrl, boolean noVersionSuffix) {
return getOAuthEndpoint(apiUrlFormat, "api", noVersionSuffix ? null : "1.1", sameOAuthSigningUrl);
public static Endpoint getOAuthRestEndpoint(@NonNull String apiUrlFormat, @AccountType String accountType,
boolean sameOAuthSigningUrl, boolean noVersionSuffix) {
return getOAuthEndpoint(apiUrlFormat, "api", noVersionSuffix ? null : "1.1", accountType, sameOAuthSigningUrl);
}
public static Endpoint getOAuthSignInEndpoint(@NonNull String apiUrlFormat, boolean sameOAuthSigningUrl) {
return getOAuthEndpoint(apiUrlFormat, "api", null, sameOAuthSigningUrl, true);
public static Endpoint getOAuthSignInEndpoint(@NonNull String apiUrlFormat, @AccountType String accountType,
boolean sameOAuthSigningUrl) {
return getOAuthEndpoint(apiUrlFormat, "api", null, accountType, sameOAuthSigningUrl, true);
}
public static Endpoint getOAuthEndpoint(String apiUrlFormat, @Nullable String domain,
@Nullable String versionSuffix,
@Nullable String versionSuffix, @AccountType String accountType,
boolean sameOAuthSigningUrl) {
return getOAuthEndpoint(apiUrlFormat, domain, versionSuffix, sameOAuthSigningUrl, false);
return getOAuthEndpoint(apiUrlFormat, domain, versionSuffix, accountType, sameOAuthSigningUrl, false);
}
public static Endpoint getOAuthEndpoint(@NonNull String apiUrlFormat, @Nullable String domain,
@Nullable String versionSuffix,
@Nullable String versionSuffix, @AccountType String accountType,
boolean sameOAuthSigningUrl, boolean fixUrl) {
String endpointUrl, signEndpointUrl;
endpointUrl = getApiUrl(apiUrlFormat, domain, versionSuffix);
String endpointUrl = getApiUrl(apiUrlFormat, domain, versionSuffix);
String signEndpointUrl = endpointUrl;
if (fixUrl) {
int[] authorityRange = UriUtils.getAuthorityRange(endpointUrl);
if (authorityRange != null && endpointUrl.regionMatches(authorityRange[0],
@ -217,10 +221,12 @@ public class MicroBlogAPIFactory implements TwidereConstants {
endpointUrl.substring(authorityRange[1]);
}
}
if (!sameOAuthSigningUrl) {
signEndpointUrl = getApiUrl(DEFAULT_TWITTER_API_URL_FORMAT, domain, versionSuffix);
} else {
if (sameOAuthSigningUrl) {
signEndpointUrl = endpointUrl;
} else if (AccountType.TWITTER.equals(accountType)) {
signEndpointUrl = getApiUrl(Constants.DEFAULT_TWITTER_API_URL_FORMAT, domain, versionSuffix);
} else if (AccountType.FANFOU.equals(accountType)) {
signEndpointUrl = endpointUrl.replace("https://", "http://");
}
return new OAuthEndpoint(endpointUrl, signEndpointUrl);
}
@ -228,7 +234,7 @@ public class MicroBlogAPIFactory implements TwidereConstants {
public static OAuthToken getOAuthToken(String consumerKey, String consumerSecret) {
if (isValidConsumerKeySecret(consumerKey) && isValidConsumerKeySecret(consumerSecret))
return new OAuthToken(consumerKey, consumerSecret);
return new OAuthToken(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET);
return new OAuthToken(Constants.TWITTER_CONSUMER_KEY, Constants.TWITTER_CONSUMER_SECRET);
}
public static boolean isValidConsumerKeySecret(@NonNull CharSequence text) {

View File

@ -327,7 +327,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
val apiConfig = activity.apiConfig
val apiUrlFormat = apiConfig.apiUrlFormat ?:
throw MicroBlogException("Invalid API URL format")
val endpoint = MicroBlogAPIFactory.getOAuthSignInEndpoint(apiUrlFormat,
val endpoint = MicroBlogAPIFactory.getOAuthSignInEndpoint(apiUrlFormat, apiConfig.type,
apiConfig.isSameOAuthUrl)
val auth = apiConfig.getOAuthAuthorization() ?:
throw MicroBlogException("Invalid OAuth credentials")
@ -338,7 +338,8 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
val activity = weakThis.get() ?: return@successUi
val intent = Intent(activity, BrowserSignInActivity::class.java)
val apiConfig = activity.apiConfig
val endpoint = MicroBlogAPIFactory.getOAuthSignInEndpoint(apiConfig.apiUrlFormat!!, true)
val endpoint = MicroBlogAPIFactory.getOAuthSignInEndpoint(apiConfig.apiUrlFormat!!,
apiConfig.type, true)
intent.data = Uri.parse(endpoint.construct("/oauth/authorize", arrayOf("oauth_token",
requestToken.oauthToken)))
intent.putExtra(EXTRA_EXTRAS, Bundle {
@ -806,7 +807,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
var auth = apiConfig.getOAuthAuthorization() ?:
throw MicroBlogException("Invalid OAuth credential")
var endpoint = MicroBlogAPIFactory.getOAuthSignInEndpoint(apiUrlFormat,
apiConfig.isSameOAuthUrl)
apiConfig.type, apiConfig.isSameOAuthUrl)
val oauth = newMicroBlogInstance(context, endpoint = endpoint, auth = auth,
accountType = apiConfig.type, cls = TwitterOAuth::class.java)
val accessToken: OAuthToken
@ -818,7 +819,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
auth = apiConfig.getOAuthAuthorization(accessToken) ?:
throw MicroBlogException("Invalid OAuth credential")
endpoint = MicroBlogAPIFactory.getOAuthEndpoint(apiUrlFormat, "api", versionSuffix,
apiConfig.isSameOAuthUrl)
apiConfig.type, apiConfig.isSameOAuthUrl)
val twitter = newMicroBlogInstance(context, endpoint = endpoint, auth = auth,
accountType = apiConfig.type, cls = MicroBlog::class.java)
@ -906,7 +907,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
private fun authOAuth(): SignInResponse {
val activity = activityRef.get() ?: throw InterruptedException()
val endpoint = MicroBlogAPIFactory.getOAuthSignInEndpoint(apiUrlFormat,
apiConfig.isSameOAuthUrl)
apiConfig.type, apiConfig.isSameOAuthUrl)
val auth = apiConfig.getOAuthAuthorization() ?:
throw MicroBlogException("Invalid OAuth credential")
val oauth = newMicroBlogInstance(activity, endpoint = endpoint, auth = auth,
@ -922,7 +923,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
private fun authxAuth(): SignInResponse {
val activity = activityRef.get() ?: throw InterruptedException()
var endpoint = MicroBlogAPIFactory.getOAuthSignInEndpoint(apiUrlFormat,
apiConfig.isSameOAuthUrl)
apiConfig.type, apiConfig.isSameOAuthUrl)
var auth = apiConfig.getOAuthAuthorization() ?:
throw MicroBlogException("Invalid OAuth credential")
val oauth = newMicroBlogInstance(activity, endpoint = endpoint, auth = auth,
@ -933,7 +934,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
auth = apiConfig.getOAuthAuthorization(accessToken) ?:
throw MicroBlogException("Invalid OAuth credential")
endpoint = MicroBlogAPIFactory.getOAuthRestEndpoint(apiUrlFormat,
apiConfig.isSameOAuthUrl, apiConfig.isNoVersionSuffix)
apiConfig.type, apiConfig.isSameOAuthUrl, apiConfig.isNoVersionSuffix)
val microBlog = newMicroBlogInstance(activity, endpoint = endpoint, auth = auth,
accountType = apiConfig.type, cls = MicroBlog::class.java)
return@run microBlog.verifyCredentials().id
@ -1013,7 +1014,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
@Credentials.Type authType: String): SignInResponse {
val auth = apiConfig.getOAuthAuthorization(accessToken) ?:
throw MicroBlogException("Invalid OAuth credential")
val endpoint = MicroBlogAPIFactory.getOAuthRestEndpoint(apiUrlFormat,
val endpoint = MicroBlogAPIFactory.getOAuthRestEndpoint(apiUrlFormat, apiConfig.type,
apiConfig.isSameOAuthUrl, apiConfig.isNoVersionSuffix)
val twitter = newMicroBlogInstance(activity, endpoint = endpoint, auth = auth,
accountType = apiConfig.type, cls = MicroBlog::class.java)
@ -1244,7 +1245,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
extras.setIsOfficialCredentials(true)
} catch (e: MicroBlogException) {
// Ignore
if (e.errorCode > 0 && e.errorCode !in ignoredTwitterErrorCodes) throw e
if (e.errorCode > 0 && e.errorCode !in ignoredTwitterErrorCodes) throw e
}
return extras
}

View File

@ -21,7 +21,7 @@ import org.mariotaku.restfu.oauth.OAuthAuthorization
import org.mariotaku.restfu.oauth.OAuthEndpoint
import org.mariotaku.restfu.oauth.OAuthToken
import org.mariotaku.restfu.oauth2.OAuth2Authorization
import org.mariotaku.twidere.TwidereConstants.DEFAULT_TWITTER_API_URL_FORMAT
import org.mariotaku.twidere.Constants.DEFAULT_TWITTER_API_URL_FORMAT
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.dagger.DependencyHolder
import org.mariotaku.twidere.model.account.cred.*
@ -33,11 +33,6 @@ import org.mariotaku.twidere.util.MicroBlogAPIFactory.sTwitterConstantPool
import org.mariotaku.twidere.util.api.*
import org.mariotaku.twidere.util.media.TwidereMediaDownloader
/**
* Creates [MicroBlog] instances
*
* Created by mariotaku on 2016/12/3.
*/
fun Credentials.getAuthorization(cls: Class<*>?): Authorization {
if (cls != null) {
when {
@ -64,7 +59,7 @@ fun Credentials.getAuthorization(cls: Class<*>?): Authorization {
throw UnsupportedOperationException()
}
fun Credentials.getEndpoint(cls: Class<*>): Endpoint {
fun Credentials.getEndpoint(@AccountType accountType: String?, cls: Class<*>): Endpoint {
val apiUrlFormat: String
val noVersionSuffix = this.no_version_suffix
if (!TextUtils.isEmpty(this.api_url_format)) {
@ -127,11 +122,13 @@ fun Credentials.getEndpoint(cls: Class<*>): Endpoint {
}
val endpointUrl = MicroBlogAPIFactory.getApiUrl(apiUrlFormat, domain, versionSuffix)
if (this is OAuthCredentials) {
val signEndpointUrl: String
if (same_oauth_signing_url) {
signEndpointUrl = endpointUrl
} else {
signEndpointUrl = MicroBlogAPIFactory.getApiUrl(DEFAULT_TWITTER_API_URL_FORMAT, domain, versionSuffix)
val signEndpointUrl = if (same_oauth_signing_url) {
endpointUrl
} else when (accountType) {
AccountType.TWITTER -> MicroBlogAPIFactory.getApiUrl(DEFAULT_TWITTER_API_URL_FORMAT,
domain, versionSuffix)
AccountType.FANFOU -> "http://api.fanfou.com/"
else -> endpointUrl
}
return OAuthEndpoint(endpointUrl, signEndpointUrl)
}
@ -140,7 +137,7 @@ fun Credentials.getEndpoint(cls: Class<*>): Endpoint {
fun <T> Credentials.newMicroBlogInstance(context: Context, @AccountType accountType: String? = null,
cls: Class<T>): T {
return newMicroBlogInstance(context, getEndpoint(cls), getAuthorization(cls), accountType, cls)
return newMicroBlogInstance(context, getEndpoint(accountType, cls), getAuthorization(cls), accountType, cls)
}
fun <T> newMicroBlogInstance(context: Context, endpoint: Endpoint, auth: Authorization,

View File

@ -33,12 +33,12 @@ import org.mariotaku.twidere.R
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.constant.SharedPreferenceConstants.*
import org.mariotaku.twidere.dagger.DependencyHolder
import org.mariotaku.twidere.extension.getDetails
import org.mariotaku.twidere.extension.model.getEndpoint
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.extension.restfu.headers
import org.mariotaku.twidere.extension.restfu.set
import org.mariotaku.twidere.model.account.cred.OAuthCredentials
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.util.DataStoreUtils
import org.mariotaku.twidere.util.MicroBlogAPIFactory
import org.mariotaku.twidere.util.net.SystemDnsFetcher
@ -121,9 +121,9 @@ class NetworkDiagnosticsFragment : BaseFragment() {
logPrintln(servers?.toString() ?: "null")
logPrintln()
val am = AccountManager.get(context)
for (accountKey in DataStoreUtils.getAccountKeys(context)) {
val details = AccountUtils.getAccountDetails(AccountManager.get(context),
accountKey, true) ?: continue
val details = am.getDetails(accountKey, true) ?: continue
logPrintln(("Testing connection for account $accountKey"))
logPrintln()
logPrintln(("api_url_format: ${details.credentials.api_url_format}"))
@ -136,7 +136,7 @@ class NetworkDiagnosticsFragment : BaseFragment() {
logPrintln(("Testing DNS functionality"))
logPrintln()
val endpoint = details.credentials.getEndpoint(MicroBlog::class.java)
val endpoint = details.credentials.getEndpoint(details.type, MicroBlog::class.java)
val uri = Uri.parse(endpoint.url)
val host = uri.host
if (host != null) {

View File

@ -341,9 +341,7 @@ abstract class AbsTimelineFragment : AbsContentRecyclerViewFragment<ParcelableSt
}
}
if (firstVisiblePosition == 0 && !preferences[readFromBottomKey]) {
recyclerView.post {
scrollToStart()
}
scrollToStart()
}
}