close #646
This commit is contained in:
parent
7bd7a151aa
commit
556e08a5f2
|
@ -6,12 +6,10 @@ import android.content.Intent;
|
|||
import android.content.SyncResult;
|
||||
import android.os.Bundle;
|
||||
|
||||
import org.mariotaku.twidere.model.SyncAuthInfo;
|
||||
|
||||
interface IDataSyncService {
|
||||
SyncAuthInfo getAuthInfo();
|
||||
String getAuthInfo();
|
||||
|
||||
Intent getAuthRequestIntent(in SyncAuthInfo info);
|
||||
Intent getAuthRequestIntent(in String info);
|
||||
|
||||
void onPerformSync(in SyncAuthInfo info, in Bundle extras, in SyncResult syncResult);
|
||||
void onPerformSync(in String info, in Bundle extras, in SyncResult syncResult);
|
||||
}
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2016 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.model;
|
||||
|
||||
parcelable SyncAuthInfo;
|
|
@ -307,5 +307,6 @@ public interface SharedPreferenceConstants {
|
|||
String KEY_DRAWER_TOGGLE = "drawer_toggle";
|
||||
|
||||
String KEY_MEDIA_LINK_COUNTS_IN_STATUS = "media_link_counts_in_status";
|
||||
String KEY_DROPBOX_ACCESS_TOKEN = "dropbox_access_token";
|
||||
|
||||
}
|
||||
|
|
|
@ -3,14 +3,25 @@ package org.mariotaku.twidere.activity
|
|||
import android.os.Bundle
|
||||
import com.dropbox.core.android.Auth
|
||||
import org.mariotaku.twidere.Constants.DROPBOX_APP_KEY
|
||||
import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_DROPBOX_ACCESS_TOKEN
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 2016/12/7.
|
||||
*/
|
||||
class DropboxAuthStarterActivity : BaseActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
Auth.startOAuth2Authentication(this, DROPBOX_APP_KEY)
|
||||
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
val oauthToken = Auth.getOAuth2Token()
|
||||
if (oauthToken != null) {
|
||||
preferences.edit().putString(KEY_DROPBOX_ACCESS_TOKEN, oauthToken).apply()
|
||||
}
|
||||
finish()
|
||||
}
|
||||
}
|
|
@ -5,9 +5,11 @@ import android.content.Intent
|
|||
import android.content.SyncResult
|
||||
import android.os.Bundle
|
||||
import android.os.IBinder
|
||||
import org.mariotaku.ktextension.convert
|
||||
import org.mariotaku.twidere.IDataSyncService
|
||||
import org.mariotaku.twidere.activity.DropboxAuthStarterActivity
|
||||
import org.mariotaku.twidere.model.SyncAuthInfo
|
||||
import org.mariotaku.twidere.util.JsonSerializer
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
/**
|
||||
|
@ -39,15 +41,18 @@ class DropboxDataSyncService : Service() {
|
|||
|
||||
internal class ServiceInterface(val service: WeakReference<DropboxDataSyncService>) : IDataSyncService.Stub() {
|
||||
|
||||
override fun getAuthInfo(): SyncAuthInfo? {
|
||||
return service.get().getAuthInfo()
|
||||
override fun getAuthInfo(): String? {
|
||||
val info = service.get().getAuthInfo() ?: return null
|
||||
return JsonSerializer.serialize(info)
|
||||
}
|
||||
|
||||
override fun getAuthRequestIntent(info: SyncAuthInfo?): Intent {
|
||||
override fun getAuthRequestIntent(infoJson: String?): Intent {
|
||||
val info = infoJson?.convert { JsonSerializer.parse(infoJson, SyncAuthInfo::class.java) }
|
||||
return service.get().getAuthRequestIntent(info)
|
||||
}
|
||||
|
||||
override fun onPerformSync(info: SyncAuthInfo, extras: Bundle?, syncResult: SyncResult) {
|
||||
override fun onPerformSync(infoJson: String, extras: Bundle?, syncResult: SyncResult) {
|
||||
val info = infoJson.convert { JsonSerializer.parse(infoJson, SyncAuthInfo::class.java) }!!
|
||||
service.get().onPerformSync(info, extras, syncResult)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,315 +0,0 @@
|
|||
package org.mariotaku.twidere.activity;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Pair;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.app.TwidereApplication;
|
||||
import org.mariotaku.twidere.model.UserKey;
|
||||
import org.mariotaku.twidere.util.BugReporter;
|
||||
import org.mariotaku.twidere.util.IntentUtils;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class WebLinkHandlerActivity extends Activity implements Constants {
|
||||
|
||||
@SuppressWarnings("SpellCheckingInspection")
|
||||
public static final String[] TWITTER_RESERVED_PATHS = {"about", "account", "accounts", "activity", "all",
|
||||
"announcements", "anywhere", "api_rules", "api_terms", "apirules", "apps", "auth", "badges", "blog",
|
||||
"business", "buttons", "contacts", "devices", "direct_messages", "download", "downloads",
|
||||
"edit_announcements", "faq", "favorites", "find_sources", "find_users", "followers", "following",
|
||||
"friend_request", "friendrequest", "friends", "goodies", "help", "home", "im_account", "inbox",
|
||||
"invitations", "invite", "jobs", "list", "login", "logo", "logout", "me", "mentions", "messages",
|
||||
"mockview", "newtwitter", "notifications", "nudge", "oauth", "phoenix_search", "positions", "privacy",
|
||||
"public_timeline", "related_tweets", "replies", "retweeted_of_mine", "retweets", "retweets_by_others",
|
||||
"rules", "saved_searches", "search", "sent", "settings", "share", "signup", "signin", "similar_to",
|
||||
"statistics", "terms", "tos", "translate", "trends", "tweetbutton", "twttr", "update_discoverability",
|
||||
"users", "welcome", "who_to_follow", "widgets", "zendesk_auth", "media_signup"};
|
||||
|
||||
@SuppressWarnings("SpellCheckingInspection")
|
||||
public static final String[] FANFOU_RESERVED_PATHS = {"home", "privatemsg", "finder", "browse",
|
||||
"search", "settings", "message", "mentions", "favorites", "friends", "followers",
|
||||
"sharer", "photo", "album", "paipai", "q", "userview", "dialogue"};
|
||||
|
||||
|
||||
private static final String AUTHORITY_TWITTER_COM = "twitter.com";
|
||||
|
||||
|
||||
private static Uri regulateTwitterUri(Uri data) {
|
||||
final String encodedFragment = data.getEncodedFragment();
|
||||
if (encodedFragment != null && encodedFragment.startsWith("!/")) {
|
||||
return regulateTwitterUri(Uri.parse("https://twitter.com" + encodedFragment.substring(1)));
|
||||
}
|
||||
final Uri.Builder builder = data.buildUpon();
|
||||
builder.scheme("https");
|
||||
builder.authority(AUTHORITY_TWITTER_COM);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
final PackageManager packageManager = getPackageManager();
|
||||
final Intent intent = getIntent();
|
||||
intent.setExtrasClassLoader(TwidereApplication.class.getClassLoader());
|
||||
final Uri uri = intent.getData();
|
||||
if (uri == null || uri.getHost() == null) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
final Pair<Intent, Boolean> handled;
|
||||
switch (uri.getHost()) {
|
||||
case "twitter.com":
|
||||
case "www.twitter.com":
|
||||
case "mobile.twitter.com": {
|
||||
handled = handleTwitterLink(regulateTwitterUri(uri));
|
||||
break;
|
||||
}
|
||||
case "fanfou.com": {
|
||||
handled = handleFanfouLink(uri);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
handled = Pair.create(null, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (handled.first != null) {
|
||||
handled.first.putExtras(intent);
|
||||
startActivity(handled.first);
|
||||
} else {
|
||||
if (!handled.second) {
|
||||
BugReporter.logException(new TwitterLinkException("Unable to handle twitter uri " + uri));
|
||||
}
|
||||
final Intent fallbackIntent = new Intent(Intent.ACTION_VIEW, uri);
|
||||
fallbackIntent.addCategory(Intent.CATEGORY_BROWSABLE);
|
||||
fallbackIntent.setPackage(IntentUtils.getDefaultBrowserPackage(this, uri, false));
|
||||
final ComponentName componentName = fallbackIntent.resolveActivity(packageManager);
|
||||
if (componentName == null) {
|
||||
final Intent targetIntent = new Intent(Intent.ACTION_VIEW, uri);
|
||||
targetIntent.addCategory(Intent.CATEGORY_BROWSABLE);
|
||||
startActivity(Intent.createChooser(targetIntent, getString(R.string.open_in_browser)));
|
||||
} else if (!TextUtils.equals(getPackageName(), componentName.getPackageName())) {
|
||||
startActivity(fallbackIntent);
|
||||
} else {
|
||||
// TODO show error
|
||||
}
|
||||
}
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private Pair<Intent, Boolean> handleFanfouLink(final Uri uri) {
|
||||
final List<String> pathSegments = uri.getPathSegments();
|
||||
if (pathSegments.size() > 0) {
|
||||
switch (pathSegments.get(0)) {
|
||||
case "statuses": {
|
||||
final Uri.Builder builder = new Uri.Builder();
|
||||
builder.scheme(SCHEME_TWIDERE);
|
||||
builder.authority(AUTHORITY_STATUS);
|
||||
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_HOST, USER_TYPE_FANFOU_COM);
|
||||
builder.appendQueryParameter(QUERY_PARAM_STATUS_ID, pathSegments.get(1));
|
||||
return Pair.create(new Intent(Intent.ACTION_VIEW, builder.build()), true);
|
||||
}
|
||||
default: {
|
||||
if (!ArrayUtils.contains(FANFOU_RESERVED_PATHS, pathSegments.get(0))) {
|
||||
if (pathSegments.size() == 1) {
|
||||
final Uri.Builder builder = new Uri.Builder();
|
||||
builder.scheme(SCHEME_TWIDERE);
|
||||
builder.authority(AUTHORITY_USER);
|
||||
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_HOST, USER_TYPE_FANFOU_COM);
|
||||
final UserKey userKey = new UserKey(pathSegments.get(0), USER_TYPE_FANFOU_COM);
|
||||
builder.appendQueryParameter(QUERY_PARAM_USER_KEY, userKey.toString());
|
||||
return Pair.create(new Intent(Intent.ACTION_VIEW, builder.build()), true);
|
||||
}
|
||||
}
|
||||
return Pair.create(null, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Pair.create(null, false);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private Pair<Intent, Boolean> handleTwitterLink(final Uri uri) {
|
||||
final List<String> pathSegments = uri.getPathSegments();
|
||||
if (pathSegments.size() > 0) {
|
||||
switch (pathSegments.get(0)) {
|
||||
case "i": {
|
||||
return getIUriIntent(uri, pathSegments);
|
||||
}
|
||||
case "intent": {
|
||||
return getTwitterIntentUriIntent(uri, pathSegments);
|
||||
}
|
||||
case "share": {
|
||||
final Intent handledIntent = new Intent(this, ComposeActivity.class);
|
||||
handledIntent.setAction(Intent.ACTION_SEND);
|
||||
final String text = uri.getQueryParameter("text");
|
||||
final String url = uri.getQueryParameter("url");
|
||||
handledIntent.putExtra(Intent.EXTRA_TEXT, Utils.getShareStatus(this, text, url));
|
||||
return Pair.create(handledIntent, true);
|
||||
}
|
||||
case "search": {
|
||||
final Uri.Builder builder = new Uri.Builder();
|
||||
builder.scheme(SCHEME_TWIDERE);
|
||||
builder.authority(AUTHORITY_SEARCH);
|
||||
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_HOST, USER_TYPE_TWITTER_COM);
|
||||
builder.appendQueryParameter(QUERY_PARAM_QUERY, uri.getQueryParameter("q"));
|
||||
return Pair.create(new Intent(Intent.ACTION_VIEW, builder.build()), true);
|
||||
}
|
||||
case "following": {
|
||||
final Uri.Builder builder = new Uri.Builder();
|
||||
builder.scheme(SCHEME_TWIDERE);
|
||||
builder.authority(AUTHORITY_USER_FRIENDS);
|
||||
builder.appendQueryParameter(QUERY_PARAM_USER_KEY, UserKey.SELF_REFERENCE.toString());
|
||||
return Pair.create(new Intent(Intent.ACTION_VIEW, builder.build()), true);
|
||||
}
|
||||
case "followers": {
|
||||
final Uri.Builder builder = new Uri.Builder();
|
||||
builder.scheme(SCHEME_TWIDERE);
|
||||
builder.authority(AUTHORITY_USER_FOLLOWERS);
|
||||
builder.appendQueryParameter(QUERY_PARAM_USER_KEY, UserKey.SELF_REFERENCE.toString());
|
||||
return Pair.create(new Intent(Intent.ACTION_VIEW, builder.build()), true);
|
||||
}
|
||||
case "favorites": {
|
||||
final Uri.Builder builder = new Uri.Builder();
|
||||
builder.scheme(SCHEME_TWIDERE);
|
||||
builder.authority(AUTHORITY_USER_FAVORITES);
|
||||
builder.appendQueryParameter(QUERY_PARAM_USER_KEY, UserKey.SELF_REFERENCE.toString());
|
||||
return Pair.create(new Intent(Intent.ACTION_VIEW, builder.build()), true);
|
||||
}
|
||||
default: {
|
||||
if (ArrayUtils.contains(TWITTER_RESERVED_PATHS, pathSegments.get(0))) {
|
||||
return Pair.create(null, true);
|
||||
}
|
||||
return handleUserSpecificPageIntent(uri, pathSegments, pathSegments.get(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
return Pair.create(null, false);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private Pair<Intent, Boolean> handleUserSpecificPageIntent(Uri uri, List<String> pathSegments, String screenName) {
|
||||
final int segsSize = pathSegments.size();
|
||||
if (segsSize == 1) {
|
||||
final Uri.Builder builder = new Uri.Builder();
|
||||
builder.scheme(SCHEME_TWIDERE);
|
||||
builder.authority(AUTHORITY_USER);
|
||||
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_HOST, USER_TYPE_TWITTER_COM);
|
||||
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName);
|
||||
return Pair.create(new Intent(Intent.ACTION_VIEW, builder.build()), true);
|
||||
} else if (segsSize == 2) {
|
||||
switch (pathSegments.get(1)) {
|
||||
case "following": {
|
||||
final Uri.Builder builder = new Uri.Builder();
|
||||
builder.scheme(SCHEME_TWIDERE);
|
||||
builder.authority(AUTHORITY_USER_FRIENDS);
|
||||
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_HOST, USER_TYPE_TWITTER_COM);
|
||||
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName);
|
||||
return Pair.create(new Intent(Intent.ACTION_VIEW, builder.build()), true);
|
||||
}
|
||||
case "followers": {
|
||||
final Uri.Builder builder = new Uri.Builder();
|
||||
builder.scheme(SCHEME_TWIDERE);
|
||||
builder.authority(AUTHORITY_USER_FOLLOWERS);
|
||||
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_HOST, USER_TYPE_TWITTER_COM);
|
||||
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName);
|
||||
return Pair.create(new Intent(Intent.ACTION_VIEW, builder.build()), true);
|
||||
}
|
||||
case "favorites": {
|
||||
final Uri.Builder builder = new Uri.Builder();
|
||||
builder.scheme(SCHEME_TWIDERE);
|
||||
builder.authority(AUTHORITY_USER_FAVORITES);
|
||||
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_HOST, USER_TYPE_TWITTER_COM);
|
||||
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName);
|
||||
return Pair.create(new Intent(Intent.ACTION_VIEW, builder.build()), true);
|
||||
}
|
||||
default: {
|
||||
final Uri.Builder builder = new Uri.Builder();
|
||||
builder.scheme(SCHEME_TWIDERE);
|
||||
builder.authority(AUTHORITY_USER_LIST);
|
||||
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_HOST, USER_TYPE_TWITTER_COM);
|
||||
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName);
|
||||
builder.appendQueryParameter(QUERY_PARAM_LIST_NAME, pathSegments.get(1));
|
||||
return Pair.create(new Intent(Intent.ACTION_VIEW, builder.build()), true);
|
||||
}
|
||||
}
|
||||
} else if (segsSize >= 3) {
|
||||
final long def = -1;
|
||||
if ("status".equals(pathSegments.get(1)) && NumberUtils.toLong(pathSegments.get(2), def) != -1) {
|
||||
final Uri.Builder builder = new Uri.Builder();
|
||||
builder.scheme(SCHEME_TWIDERE);
|
||||
builder.authority(AUTHORITY_STATUS);
|
||||
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_HOST, USER_TYPE_TWITTER_COM);
|
||||
builder.appendQueryParameter(QUERY_PARAM_STATUS_ID, pathSegments.get(2));
|
||||
return Pair.create(new Intent(Intent.ACTION_VIEW, builder.build()), true);
|
||||
} else {
|
||||
switch (pathSegments.get(2)) {
|
||||
case "members": {
|
||||
final Uri.Builder builder = new Uri.Builder();
|
||||
builder.scheme(SCHEME_TWIDERE);
|
||||
builder.authority(AUTHORITY_USER_LIST_MEMBERS);
|
||||
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_HOST, USER_TYPE_TWITTER_COM);
|
||||
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName);
|
||||
builder.appendQueryParameter(QUERY_PARAM_LIST_NAME, pathSegments.get(1));
|
||||
return Pair.create(new Intent(Intent.ACTION_VIEW, builder.build()), true);
|
||||
}
|
||||
case "subscribers": {
|
||||
final Uri.Builder builder = new Uri.Builder();
|
||||
builder.scheme(SCHEME_TWIDERE);
|
||||
builder.authority(AUTHORITY_USER_LIST_SUBSCRIBERS);
|
||||
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_HOST, USER_TYPE_TWITTER_COM);
|
||||
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName);
|
||||
builder.appendQueryParameter(QUERY_PARAM_LIST_NAME, pathSegments.get(1));
|
||||
return Pair.create(new Intent(Intent.ACTION_VIEW, builder.build()), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Pair.create(null, false);
|
||||
}
|
||||
|
||||
private Pair<Intent, Boolean> getTwitterIntentUriIntent(Uri uri, List<String> pathSegments) {
|
||||
if (pathSegments.size() < 2) return Pair.create(null, false);
|
||||
switch (pathSegments.get(1)) {
|
||||
case "tweet": {
|
||||
final Intent handledIntent = new Intent(this, ComposeActivity.class);
|
||||
handledIntent.setAction(Intent.ACTION_SEND);
|
||||
final String text = uri.getQueryParameter("text");
|
||||
final String url = uri.getQueryParameter("url");
|
||||
handledIntent.putExtra(Intent.EXTRA_TEXT, Utils.getShareStatus(this, text, url));
|
||||
return Pair.create(handledIntent, true);
|
||||
}
|
||||
}
|
||||
return Pair.create(null, false);
|
||||
}
|
||||
|
||||
private Pair<Intent, Boolean> getIUriIntent(Uri uri, List<String> pathSegments) {
|
||||
return Pair.create(null, false);
|
||||
}
|
||||
|
||||
private class TwitterLinkException extends Exception {
|
||||
public TwitterLinkException(final String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -53,6 +53,7 @@ import android.widget.Toast
|
|||
import com.bluelinelabs.logansquare.LoganSquare
|
||||
import com.rengwuxian.materialedittext.MaterialEditText
|
||||
import kotlinx.android.synthetic.main.activity_sign_in.*
|
||||
import org.mariotaku.ktextension.set
|
||||
import org.mariotaku.microblog.library.MicroBlog
|
||||
import org.mariotaku.microblog.library.MicroBlogException
|
||||
import org.mariotaku.microblog.library.twitter.TwitterOAuth
|
||||
|
@ -88,6 +89,7 @@ import org.mariotaku.twidere.util.*
|
|||
import org.mariotaku.twidere.util.OAuthPasswordAuthenticator.*
|
||||
import org.mariotaku.twidere.util.view.ConsumerKeySecretValidator
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.*
|
||||
|
||||
|
||||
class SignInActivity : BaseActivity(), OnClickListener, TextWatcher {
|
||||
|
@ -730,37 +732,49 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher {
|
|||
|
||||
internal data class SignInResponse(
|
||||
val alreadyLoggedIn: Boolean,
|
||||
@Credentials.Type val authType: String = Credentials.Type.EMPTY,
|
||||
@Credentials.Type val credsType: String = Credentials.Type.EMPTY,
|
||||
val credentials: Credentials,
|
||||
val user: ParcelableUser,
|
||||
val color: Int = 0,
|
||||
val accountType: Pair<String, String>? = null
|
||||
val accountType: Pair<String, String>
|
||||
) {
|
||||
|
||||
fun writeAccountInfo(am: AccountManager, account: Account) {
|
||||
am.setUserData(account, ACCOUNT_USER_DATA_KEY, user.key.toString())
|
||||
am.setUserData(account, ACCOUNT_USER_DATA_USER, LoganSquare.serialize(user))
|
||||
private fun writeAccountInfo(map: MutableMap<String, String?>) {
|
||||
map[ACCOUNT_USER_DATA_KEY] = user.key.toString()
|
||||
map[ACCOUNT_USER_DATA_TYPE] = accountType.first
|
||||
map[ACCOUNT_USER_DATA_CREDS_TYPE] = credsType
|
||||
|
||||
am.setUserData(account, ACCOUNT_USER_DATA_COLOR, toHexColor(color))
|
||||
am.setUserData(account, ACCOUNT_USER_DATA_ACTIVATED, true.toString())
|
||||
map[ACCOUNT_USER_DATA_ACTIVATED] = true.toString()
|
||||
map[ACCOUNT_USER_DATA_COLOR] = toHexColor(color)
|
||||
|
||||
map[ACCOUNT_USER_DATA_USER] = LoganSquare.serialize(user)
|
||||
map[ACCOUNT_USER_DATA_EXTRAS] = accountType.second
|
||||
}
|
||||
|
||||
private fun writeAuthToken(am: AccountManager, account: Account) {
|
||||
am.setAuthToken(account, ACCOUNT_AUTH_TOKEN_TYPE, LoganSquare.serialize(credentials))
|
||||
|
||||
if (accountType != null) {
|
||||
am.setUserData(account, ACCOUNT_USER_DATA_TYPE, accountType.first)
|
||||
am.setUserData(account, ACCOUNT_USER_DATA_EXTRAS, accountType.second)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateAccount(am: AccountManager) {
|
||||
val account = AccountUtils.findByAccountKey(am, user.key) ?: return
|
||||
writeAccountInfo(am, account)
|
||||
val map: MutableMap<String, String?> = HashMap()
|
||||
writeAccountInfo(map)
|
||||
for ((k, v) in map) {
|
||||
am.setUserData(account, k, v)
|
||||
}
|
||||
writeAuthToken(am, account)
|
||||
}
|
||||
|
||||
fun insertAccount(am: AccountManager) {
|
||||
fun insertAccount(am: AccountManager): Account {
|
||||
val account = Account(UserKey(user.screen_name, user.key.host).toString(), ACCOUNT_TYPE)
|
||||
am.addAccountExplicitly(account, null, null)
|
||||
writeAccountInfo(am, account)
|
||||
val map: MutableMap<String, String?> = HashMap()
|
||||
writeAccountInfo(map)
|
||||
val userData = Bundle()
|
||||
for ((k, v) in map) {
|
||||
userData[k] = v
|
||||
}
|
||||
am.addAccountExplicitly(account, null, userData)
|
||||
return account
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,291 @@
|
|||
package org.mariotaku.twidere.activity
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.util.Pair
|
||||
import org.apache.commons.lang3.ArrayUtils
|
||||
import org.mariotaku.ktextension.toLong
|
||||
import org.mariotaku.twidere.Constants
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.TwidereConstants.*
|
||||
import org.mariotaku.twidere.app.TwidereApplication
|
||||
import org.mariotaku.twidere.model.UserKey
|
||||
import org.mariotaku.twidere.util.BugReporter
|
||||
import org.mariotaku.twidere.util.IntentUtils
|
||||
import org.mariotaku.twidere.util.Utils
|
||||
|
||||
class WebLinkHandlerActivity : Activity(), Constants {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
val packageManager = packageManager
|
||||
val intent = intent
|
||||
intent.setExtrasClassLoader(TwidereApplication::class.java.classLoader)
|
||||
val uri = intent.data
|
||||
if (uri == null || uri.host == null) {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
val handled: Pair<Intent, Boolean>
|
||||
when (uri.host) {
|
||||
"twitter.com", "www.twitter.com", "mobile.twitter.com" -> {
|
||||
handled = handleTwitterLink(regulateTwitterUri(uri))
|
||||
}
|
||||
"fanfou.com" -> {
|
||||
handled = handleFanfouLink(uri)
|
||||
}
|
||||
else -> {
|
||||
handled = Pair.create<Intent, Boolean>(null, false)
|
||||
}
|
||||
}
|
||||
if (handled.first != null) {
|
||||
handled.first.putExtras(intent)
|
||||
startActivity(handled.first)
|
||||
} else {
|
||||
if (!handled.second) {
|
||||
BugReporter.logException(TwitterLinkException("Unable to handle twitter uri " + uri))
|
||||
}
|
||||
val fallbackIntent = Intent(Intent.ACTION_VIEW, uri)
|
||||
fallbackIntent.addCategory(Intent.CATEGORY_BROWSABLE)
|
||||
fallbackIntent.`package` = IntentUtils.getDefaultBrowserPackage(this, uri, false)
|
||||
val componentName = fallbackIntent.resolveActivity(packageManager)
|
||||
if (componentName == null) {
|
||||
val targetIntent = Intent(Intent.ACTION_VIEW, uri)
|
||||
targetIntent.addCategory(Intent.CATEGORY_BROWSABLE)
|
||||
startActivity(Intent.createChooser(targetIntent, getString(R.string.open_in_browser)))
|
||||
} else if (!TextUtils.equals(packageName, componentName.packageName)) {
|
||||
startActivity(fallbackIntent)
|
||||
} else {
|
||||
// TODO show error
|
||||
}
|
||||
}
|
||||
finish()
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
setVisible(true)
|
||||
}
|
||||
|
||||
private fun handleFanfouLink(uri: Uri): Pair<Intent, Boolean> {
|
||||
val pathSegments = uri.pathSegments
|
||||
if (pathSegments.size > 0) {
|
||||
when (pathSegments[0]) {
|
||||
"statuses" -> {
|
||||
val builder = Uri.Builder()
|
||||
builder.scheme(SCHEME_TWIDERE)
|
||||
builder.authority(AUTHORITY_STATUS)
|
||||
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_HOST, USER_TYPE_FANFOU_COM)
|
||||
builder.appendQueryParameter(QUERY_PARAM_STATUS_ID, pathSegments[1])
|
||||
return Pair.create(Intent(Intent.ACTION_VIEW, builder.build()), true)
|
||||
}
|
||||
else -> {
|
||||
if (!ArrayUtils.contains(FANFOU_RESERVED_PATHS, pathSegments[0])) {
|
||||
if (pathSegments.size == 1) {
|
||||
val builder = Uri.Builder()
|
||||
builder.scheme(SCHEME_TWIDERE)
|
||||
builder.authority(AUTHORITY_USER)
|
||||
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_HOST, USER_TYPE_FANFOU_COM)
|
||||
val userKey = UserKey(pathSegments[0], USER_TYPE_FANFOU_COM)
|
||||
builder.appendQueryParameter(QUERY_PARAM_USER_KEY, userKey.toString())
|
||||
return Pair.create(Intent(Intent.ACTION_VIEW, builder.build()), true)
|
||||
}
|
||||
}
|
||||
return Pair.create<Intent, Boolean>(null, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
return Pair.create<Intent, Boolean>(null, false)
|
||||
}
|
||||
|
||||
private fun handleTwitterLink(uri: Uri): Pair<Intent, Boolean> {
|
||||
val pathSegments = uri.pathSegments
|
||||
if (pathSegments.size > 0) {
|
||||
when (pathSegments[0]) {
|
||||
"i" -> {
|
||||
return getIUriIntent(uri, pathSegments)
|
||||
}
|
||||
"intent" -> {
|
||||
return getTwitterIntentUriIntent(uri, pathSegments)
|
||||
}
|
||||
"share" -> {
|
||||
val handledIntent = Intent(this, ComposeActivity::class.java)
|
||||
handledIntent.action = Intent.ACTION_SEND
|
||||
val text = uri.getQueryParameter("text")
|
||||
val url = uri.getQueryParameter("url")
|
||||
handledIntent.putExtra(Intent.EXTRA_TEXT, Utils.getShareStatus(this, text, url))
|
||||
return Pair.create(handledIntent, true)
|
||||
}
|
||||
"search" -> {
|
||||
val builder = Uri.Builder()
|
||||
builder.scheme(SCHEME_TWIDERE)
|
||||
builder.authority(AUTHORITY_SEARCH)
|
||||
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_HOST, USER_TYPE_TWITTER_COM)
|
||||
builder.appendQueryParameter(QUERY_PARAM_QUERY, uri.getQueryParameter("q"))
|
||||
return Pair.create(Intent(Intent.ACTION_VIEW, builder.build()), true)
|
||||
}
|
||||
"hashtag" -> {
|
||||
val builder = Uri.Builder()
|
||||
builder.scheme(SCHEME_TWIDERE)
|
||||
builder.authority(AUTHORITY_SEARCH)
|
||||
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_HOST, USER_TYPE_TWITTER_COM)
|
||||
builder.appendQueryParameter(QUERY_PARAM_QUERY, "#${uri.lastPathSegment}")
|
||||
return Pair.create(Intent(Intent.ACTION_VIEW, builder.build()), true)
|
||||
}
|
||||
"following" -> {
|
||||
val builder = Uri.Builder()
|
||||
builder.scheme(SCHEME_TWIDERE)
|
||||
builder.authority(AUTHORITY_USER_FRIENDS)
|
||||
builder.appendQueryParameter(QUERY_PARAM_USER_KEY, UserKey.SELF_REFERENCE.toString())
|
||||
return Pair.create(Intent(Intent.ACTION_VIEW, builder.build()), true)
|
||||
}
|
||||
"followers" -> {
|
||||
val builder = Uri.Builder()
|
||||
builder.scheme(SCHEME_TWIDERE)
|
||||
builder.authority(AUTHORITY_USER_FOLLOWERS)
|
||||
builder.appendQueryParameter(QUERY_PARAM_USER_KEY, UserKey.SELF_REFERENCE.toString())
|
||||
return Pair.create(Intent(Intent.ACTION_VIEW, builder.build()), true)
|
||||
}
|
||||
"favorites" -> {
|
||||
val builder = Uri.Builder()
|
||||
builder.scheme(SCHEME_TWIDERE)
|
||||
builder.authority(AUTHORITY_USER_FAVORITES)
|
||||
builder.appendQueryParameter(QUERY_PARAM_USER_KEY, UserKey.SELF_REFERENCE.toString())
|
||||
return Pair.create(Intent(Intent.ACTION_VIEW, builder.build()), true)
|
||||
}
|
||||
else -> {
|
||||
if (ArrayUtils.contains(TWITTER_RESERVED_PATHS, pathSegments[0])) {
|
||||
return Pair.create<Intent, Boolean>(null, true)
|
||||
}
|
||||
return handleUserSpecificPageIntent(uri, pathSegments, pathSegments[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
return Pair.create<Intent, Boolean>(null, false)
|
||||
}
|
||||
|
||||
private fun handleUserSpecificPageIntent(uri: Uri, pathSegments: List<String>, screenName: String): Pair<Intent, Boolean> {
|
||||
val segsSize = pathSegments.size
|
||||
if (segsSize == 1) {
|
||||
val builder = Uri.Builder()
|
||||
builder.scheme(SCHEME_TWIDERE)
|
||||
builder.authority(AUTHORITY_USER)
|
||||
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_HOST, USER_TYPE_TWITTER_COM)
|
||||
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName)
|
||||
return Pair.create(Intent(Intent.ACTION_VIEW, builder.build()), true)
|
||||
} else if (segsSize == 2) {
|
||||
when (pathSegments[1]) {
|
||||
"following" -> {
|
||||
val builder = Uri.Builder()
|
||||
builder.scheme(SCHEME_TWIDERE)
|
||||
builder.authority(AUTHORITY_USER_FRIENDS)
|
||||
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_HOST, USER_TYPE_TWITTER_COM)
|
||||
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName)
|
||||
return Pair.create(Intent(Intent.ACTION_VIEW, builder.build()), true)
|
||||
}
|
||||
"followers" -> {
|
||||
val builder = Uri.Builder()
|
||||
builder.scheme(SCHEME_TWIDERE)
|
||||
builder.authority(AUTHORITY_USER_FOLLOWERS)
|
||||
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_HOST, USER_TYPE_TWITTER_COM)
|
||||
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName)
|
||||
return Pair.create(Intent(Intent.ACTION_VIEW, builder.build()), true)
|
||||
}
|
||||
"favorites" -> {
|
||||
val builder = Uri.Builder()
|
||||
builder.scheme(SCHEME_TWIDERE)
|
||||
builder.authority(AUTHORITY_USER_FAVORITES)
|
||||
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_HOST, USER_TYPE_TWITTER_COM)
|
||||
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName)
|
||||
return Pair.create(Intent(Intent.ACTION_VIEW, builder.build()), true)
|
||||
}
|
||||
else -> {
|
||||
val builder = Uri.Builder()
|
||||
builder.scheme(SCHEME_TWIDERE)
|
||||
builder.authority(AUTHORITY_USER_LIST)
|
||||
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_HOST, USER_TYPE_TWITTER_COM)
|
||||
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName)
|
||||
builder.appendQueryParameter(QUERY_PARAM_LIST_NAME, pathSegments[1])
|
||||
return Pair.create(Intent(Intent.ACTION_VIEW, builder.build()), true)
|
||||
}
|
||||
}
|
||||
} else if (segsSize >= 3) {
|
||||
if ("status" == pathSegments[1] && pathSegments[2].toLong(-1) != -1L) {
|
||||
val builder = Uri.Builder()
|
||||
builder.scheme(SCHEME_TWIDERE)
|
||||
builder.authority(AUTHORITY_STATUS)
|
||||
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_HOST, USER_TYPE_TWITTER_COM)
|
||||
builder.appendQueryParameter(QUERY_PARAM_STATUS_ID, pathSegments[2])
|
||||
return Pair.create(Intent(Intent.ACTION_VIEW, builder.build()), true)
|
||||
} else {
|
||||
when (pathSegments[2]) {
|
||||
"members" -> {
|
||||
val builder = Uri.Builder()
|
||||
builder.scheme(SCHEME_TWIDERE)
|
||||
builder.authority(AUTHORITY_USER_LIST_MEMBERS)
|
||||
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_HOST, USER_TYPE_TWITTER_COM)
|
||||
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName)
|
||||
builder.appendQueryParameter(QUERY_PARAM_LIST_NAME, pathSegments[1])
|
||||
return Pair.create(Intent(Intent.ACTION_VIEW, builder.build()), true)
|
||||
}
|
||||
"subscribers" -> {
|
||||
val builder = Uri.Builder()
|
||||
builder.scheme(SCHEME_TWIDERE)
|
||||
builder.authority(AUTHORITY_USER_LIST_SUBSCRIBERS)
|
||||
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_HOST, USER_TYPE_TWITTER_COM)
|
||||
builder.appendQueryParameter(QUERY_PARAM_SCREEN_NAME, screenName)
|
||||
builder.appendQueryParameter(QUERY_PARAM_LIST_NAME, pathSegments[1])
|
||||
return Pair.create(Intent(Intent.ACTION_VIEW, builder.build()), true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Pair.create<Intent, Boolean>(null, false)
|
||||
}
|
||||
|
||||
private fun getTwitterIntentUriIntent(uri: Uri, pathSegments: List<String>): Pair<Intent, Boolean> {
|
||||
if (pathSegments.size < 2) return Pair.create<Intent, Boolean>(null, false)
|
||||
when (pathSegments[1]) {
|
||||
"tweet" -> {
|
||||
val handledIntent = Intent(this, ComposeActivity::class.java)
|
||||
handledIntent.action = Intent.ACTION_SEND
|
||||
val text = uri.getQueryParameter("text")
|
||||
val url = uri.getQueryParameter("url")
|
||||
handledIntent.putExtra(Intent.EXTRA_TEXT, Utils.getShareStatus(this, text, url))
|
||||
return Pair.create(handledIntent, true)
|
||||
}
|
||||
}
|
||||
return Pair.create<Intent, Boolean>(null, false)
|
||||
}
|
||||
|
||||
private fun getIUriIntent(uri: Uri, pathSegments: List<String>): Pair<Intent, Boolean> {
|
||||
return Pair.create<Intent, Boolean>(null, false)
|
||||
}
|
||||
|
||||
private inner class TwitterLinkException(s: String) : Exception(s)
|
||||
|
||||
companion object {
|
||||
|
||||
val TWITTER_RESERVED_PATHS = arrayOf("about", "account", "accounts", "activity", "all", "announcements", "anywhere", "api_rules", "api_terms", "apirules", "apps", "auth", "badges", "blog", "business", "buttons", "contacts", "devices", "direct_messages", "download", "downloads", "edit_announcements", "faq", "favorites", "find_sources", "find_users", "followers", "following", "friend_request", "friendrequest", "friends", "goodies", "help", "home", "im_account", "inbox", "invitations", "invite", "jobs", "list", "login", "logo", "logout", "me", "mentions", "messages", "mockview", "newtwitter", "notifications", "nudge", "oauth", "phoenix_search", "positions", "privacy", "public_timeline", "related_tweets", "replies", "retweeted_of_mine", "retweets", "retweets_by_others", "rules", "saved_searches", "search", "sent", "settings", "share", "signup", "signin", "similar_to", "statistics", "terms", "tos", "translate", "trends", "tweetbutton", "twttr", "update_discoverability", "users", "welcome", "who_to_follow", "widgets", "zendesk_auth", "media_signup")
|
||||
|
||||
val FANFOU_RESERVED_PATHS = arrayOf("home", "privatemsg", "finder", "browse", "search", "settings", "message", "mentions", "favorites", "friends", "followers", "sharer", "photo", "album", "paipai", "q", "userview", "dialogue")
|
||||
|
||||
|
||||
private val AUTHORITY_TWITTER_COM = "twitter.com"
|
||||
|
||||
|
||||
private fun regulateTwitterUri(data: Uri): Uri {
|
||||
val encodedFragment = data.encodedFragment
|
||||
if (encodedFragment != null && encodedFragment.startsWith("!/")) {
|
||||
return regulateTwitterUri(Uri.parse("https://twitter.com" + encodedFragment.substring(1)))
|
||||
}
|
||||
val builder = data.buildUpon()
|
||||
builder.scheme("https")
|
||||
builder.authority(AUTHORITY_TWITTER_COM)
|
||||
return builder.build()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -28,10 +28,9 @@ import android.view.View
|
|||
import android.view.ViewGroup
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_MEDIA_PREVIEW_STYLE
|
||||
import org.mariotaku.twidere.extension.getActionName
|
||||
import org.mariotaku.twidere.model.Draft
|
||||
import org.mariotaku.twidere.model.DraftCursorIndices
|
||||
import org.mariotaku.twidere.model.ParcelableMediaUpdate
|
||||
import org.mariotaku.twidere.model.UserKey
|
||||
import org.mariotaku.twidere.model.util.ParcelableMediaUtils
|
||||
import org.mariotaku.twidere.util.*
|
||||
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
|
||||
|
@ -47,7 +46,11 @@ class DraftsAdapter(context: Context) : SimpleCursorAdapter(context, R.layout.li
|
|||
private val mediaLoadingHandler: MediaLoadingHandler
|
||||
private val mediaPreviewStyle: Int
|
||||
|
||||
private var mTextSize: Float = 0.toFloat()
|
||||
var textSize: Float = 0f
|
||||
set(value) {
|
||||
field = value
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
private var indices: DraftCursorIndices? = null
|
||||
|
||||
init {
|
||||
|
@ -57,17 +60,18 @@ class DraftsAdapter(context: Context) : SimpleCursorAdapter(context, R.layout.li
|
|||
}
|
||||
|
||||
override fun bindView(view: View, context: Context, cursor: Cursor) {
|
||||
val draft = indices?.newObject(cursor) ?: return
|
||||
val holder = view.tag as DraftViewHolder
|
||||
val indices = indices!!
|
||||
val accountKeys = UserKey.arrayOf(cursor.getString(indices.account_keys))
|
||||
val text = cursor.getString(indices.text)
|
||||
val mediaUpdates = JsonSerializer.parseArray(cursor.getString(indices.media), ParcelableMediaUpdate::class.java)
|
||||
val timestamp = cursor.getLong(indices.timestamp)
|
||||
val actionType: String = cursor.getString(indices.action_type) ?: Draft.Action.UPDATE_STATUS
|
||||
val actionName = getActionName(context, actionType)
|
||||
val accountKeys = draft.account_keys
|
||||
val text = draft.text
|
||||
val mediaUpdates = draft.media
|
||||
val timestamp = draft.timestamp
|
||||
val actionType: String = draft.action_type ?: Draft.Action.UPDATE_STATUS
|
||||
val actionName = draft.getActionName(context)
|
||||
holder.media_preview_container.setStyle(mediaPreviewStyle)
|
||||
when (actionType) {
|
||||
Draft.Action.UPDATE_STATUS, Draft.Action.UPDATE_STATUS_COMPAT_1, Draft.Action.UPDATE_STATUS_COMPAT_2, Draft.Action.REPLY, Draft.Action.QUOTE -> {
|
||||
Draft.Action.UPDATE_STATUS, Draft.Action.UPDATE_STATUS_COMPAT_1,
|
||||
Draft.Action.UPDATE_STATUS_COMPAT_2, Draft.Action.REPLY, Draft.Action.QUOTE -> {
|
||||
val media = ParcelableMediaUtils.fromMediaUpdates(mediaUpdates)
|
||||
holder.media_preview_container.visibility = View.VISIBLE
|
||||
holder.media_preview_container.displayMedia(media, imageLoader, null, -1, null,
|
||||
|
@ -82,7 +86,7 @@ class DraftsAdapter(context: Context) : SimpleCursorAdapter(context, R.layout.li
|
|||
} else {
|
||||
holder.content.drawEnd()
|
||||
}
|
||||
holder.setTextSize(mTextSize)
|
||||
holder.setTextSize(textSize)
|
||||
val emptyContent = TextUtils.isEmpty(text)
|
||||
if (emptyContent) {
|
||||
holder.text.setText(R.string.empty_content)
|
||||
|
@ -108,10 +112,6 @@ class DraftsAdapter(context: Context) : SimpleCursorAdapter(context, R.layout.li
|
|||
return view
|
||||
}
|
||||
|
||||
fun setTextSize(text_size: Float) {
|
||||
mTextSize = text_size
|
||||
}
|
||||
|
||||
override fun swapCursor(c: Cursor?): Cursor? {
|
||||
val old = super.swapCursor(c)
|
||||
if (c != null) {
|
||||
|
@ -124,23 +124,4 @@ class DraftsAdapter(context: Context) : SimpleCursorAdapter(context, R.layout.li
|
|||
cursor.moveToPosition(position)
|
||||
return indices!!.newObject(cursor)
|
||||
}
|
||||
|
||||
private fun getActionName(context: Context, actionType: String): String? {
|
||||
if (TextUtils.isEmpty(actionType)) return context.getString(R.string.update_status)
|
||||
when (actionType) {
|
||||
Draft.Action.UPDATE_STATUS, Draft.Action.UPDATE_STATUS_COMPAT_1, Draft.Action.UPDATE_STATUS_COMPAT_2 -> {
|
||||
return context.getString(R.string.update_status)
|
||||
}
|
||||
Draft.Action.REPLY -> {
|
||||
return context.getString(R.string.reply)
|
||||
}
|
||||
Draft.Action.QUOTE -> {
|
||||
return context.getString(R.string.quote)
|
||||
}
|
||||
Draft.Action.SEND_DIRECT_MESSAGE, Draft.Action.SEND_DIRECT_MESSAGE_COMPAT -> {
|
||||
return context.getString(R.string.send_direct_message)
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.mariotaku.twidere.extension
|
|||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.text.TextUtils
|
||||
import com.bluelinelabs.logansquare.LoganSquare
|
||||
import com.nostra13.universalimageloader.utils.IoUtils
|
||||
import org.apache.james.mime4j.dom.Header
|
||||
|
@ -18,6 +19,7 @@ import org.apache.james.mime4j.util.MimeUtil
|
|||
import org.mariotaku.ktextension.convert
|
||||
import org.mariotaku.ktextension.toInt
|
||||
import org.mariotaku.ktextension.toString
|
||||
import org.mariotaku.twidere.R
|
||||
import org.mariotaku.twidere.extension.model.getMimeType
|
||||
import org.mariotaku.twidere.model.*
|
||||
import org.mariotaku.twidere.model.Draft.Action
|
||||
|
@ -47,7 +49,9 @@ fun Draft.writeMimeMessageTo(context: Context, st: OutputStream) {
|
|||
val message = builder.newMessage() as AbstractMessage
|
||||
|
||||
message.date = Date(this.timestamp)
|
||||
message.subject = this.getActionName(context)
|
||||
message.setFrom(this.account_keys?.map { Mailbox(it.id, it.host) })
|
||||
message.setTo(message.from)
|
||||
if (message.header == null) {
|
||||
message.header = HeaderImpl()
|
||||
}
|
||||
|
@ -97,6 +101,25 @@ fun Draft.readMimeMessageFrom(context: Context, st: InputStream) {
|
|||
parser.parse(st)
|
||||
}
|
||||
|
||||
fun Draft.getActionName(context: Context): String? {
|
||||
if (TextUtils.isEmpty(action_type)) return context.getString(R.string.update_status)
|
||||
when (action_type) {
|
||||
Draft.Action.UPDATE_STATUS, Draft.Action.UPDATE_STATUS_COMPAT_1, Draft.Action.UPDATE_STATUS_COMPAT_2 -> {
|
||||
return context.getString(R.string.update_status)
|
||||
}
|
||||
Draft.Action.REPLY -> {
|
||||
return context.getString(R.string.reply)
|
||||
}
|
||||
Draft.Action.QUOTE -> {
|
||||
return context.getString(R.string.quote)
|
||||
}
|
||||
Draft.Action.SEND_DIRECT_MESSAGE, Draft.Action.SEND_DIRECT_MESSAGE_COMPAT -> {
|
||||
return context.getString(R.string.send_direct_message)
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private class DraftContentHandler(private val context: Context, private val draft: Draft) : SimpleContentHandler() {
|
||||
private val processingStack = Stack<SimpleContentHandler>()
|
||||
private val mediaList: MutableList<ParcelableMediaUpdate> = ArrayList()
|
||||
|
|
|
@ -73,8 +73,7 @@ import java.util.*
|
|||
|
||||
class DraftsFragment : BaseSupportFragment(), LoaderCallbacks<Cursor?>, OnItemClickListener, MultiChoiceModeListener {
|
||||
|
||||
private var adapter: DraftsAdapter? = null
|
||||
|
||||
private lateinit var adapter: DraftsAdapter
|
||||
|
||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||
mode.menuInflater.inflate(R.menu.action_multi_select_drafts, menu)
|
||||
|
@ -101,7 +100,7 @@ class DraftsFragment : BaseSupportFragment(), LoaderCallbacks<Cursor?>, OnItemCl
|
|||
for (i in 0 until checked.size()) {
|
||||
val position = checked.keyAt(i)
|
||||
if (checked.valueAt(i)) {
|
||||
list.add(adapter!!.getDraft(position))
|
||||
list.add(adapter.getDraft(position))
|
||||
}
|
||||
}
|
||||
if (sendDrafts(list)) {
|
||||
|
@ -116,7 +115,7 @@ class DraftsFragment : BaseSupportFragment(), LoaderCallbacks<Cursor?>, OnItemCl
|
|||
for (i in 0 until checked.size()) {
|
||||
val position = checked.keyAt(i)
|
||||
if (checked.valueAt(i)) {
|
||||
drafts.add(adapter!!.getDraft(position))
|
||||
drafts.add(adapter.getDraft(position))
|
||||
}
|
||||
}
|
||||
task {
|
||||
|
@ -157,12 +156,12 @@ class DraftsFragment : BaseSupportFragment(), LoaderCallbacks<Cursor?>, OnItemCl
|
|||
}
|
||||
|
||||
override fun onLoadFinished(loader: Loader<Cursor?>, cursor: Cursor?) {
|
||||
adapter!!.swapCursor(cursor)
|
||||
adapter.swapCursor(cursor)
|
||||
setListShown(true)
|
||||
}
|
||||
|
||||
override fun onLoaderReset(loader: Loader<Cursor?>) {
|
||||
adapter!!.swapCursor(null)
|
||||
adapter.swapCursor(null)
|
||||
}
|
||||
|
||||
override fun onItemCheckedStateChanged(mode: ActionMode, position: Int, id: Long,
|
||||
|
@ -171,7 +170,7 @@ class DraftsFragment : BaseSupportFragment(), LoaderCallbacks<Cursor?>, OnItemCl
|
|||
}
|
||||
|
||||
override fun onItemClick(view: AdapterView<*>, child: View, position: Int, id: Long) {
|
||||
val item = adapter!!.getDraft(position)
|
||||
val item = adapter.getDraft(position)
|
||||
if (TextUtils.isEmpty(item.action_type)) {
|
||||
editDraft(item)
|
||||
return
|
||||
|
@ -183,14 +182,16 @@ class DraftsFragment : BaseSupportFragment(), LoaderCallbacks<Cursor?>, OnItemCl
|
|||
}
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater!!.inflate(R.layout.fragment_drafts, container, false)
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_drafts, container, false)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
adapter = DraftsAdapter(activity)
|
||||
adapter!!.setTextSize(preferences.getInt(KEY_TEXT_SIZE, getDefaultTextSize(activity)).toFloat())
|
||||
adapter = DraftsAdapter(activity).apply {
|
||||
textSize = preferences.getInt(KEY_TEXT_SIZE, getDefaultTextSize(activity)).toFloat()
|
||||
}
|
||||
|
||||
listView.adapter = adapter
|
||||
listView.emptyView = emptyView
|
||||
listView.onItemClickListener = this
|
||||
|
@ -212,9 +213,9 @@ class DraftsFragment : BaseSupportFragment(), LoaderCallbacks<Cursor?>, OnItemCl
|
|||
}
|
||||
|
||||
fun setListShown(listShown: Boolean) {
|
||||
listContainer!!.visibility = if (listShown) View.VISIBLE else View.GONE
|
||||
progressContainer!!.visibility = if (listShown) View.GONE else View.VISIBLE
|
||||
emptyView!!.visibility = if (listShown && adapter!!.isEmpty) View.VISIBLE else View.GONE
|
||||
listContainer.visibility = if (listShown) View.VISIBLE else View.GONE
|
||||
progressContainer.visibility = if (listShown) View.GONE else View.VISIBLE
|
||||
emptyView.visibility = if (listShown && adapter.isEmpty) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
private fun editDraft(draft: Draft) {
|
||||
|
@ -242,7 +243,7 @@ class DraftsFragment : BaseSupportFragment(), LoaderCallbacks<Cursor?>, OnItemCl
|
|||
if (item.account_keys?.isEmpty() ?: true || recipientId == null) {
|
||||
continue@loop
|
||||
}
|
||||
val accountId = item.account_keys!![0]
|
||||
val accountId = item.account_keys?.firstOrNull()
|
||||
val imageUri = item.media?.firstOrNull()?.uri
|
||||
twitterWrapper.sendDirectMessageAsync(accountId, recipientId, item.text, imageUri)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue