fixed #508
improved sign in
This commit is contained in:
Mariotaku Lee 2016-04-18 14:29:44 +08:00
parent 00242ed01a
commit b5d05e1112
12 changed files with 268 additions and 85 deletions

View File

@ -48,6 +48,7 @@ import org.mariotaku.restfu.annotation.method.GET;
import org.mariotaku.restfu.http.HttpRequest;
import org.mariotaku.restfu.http.HttpResponse;
import org.mariotaku.restfu.http.RestHttpClient;
import org.mariotaku.twidere.BuildConfig;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.ArrayAdapter;
import org.mariotaku.twidere.fragment.BaseSupportDialogFragment;
@ -294,7 +295,9 @@ public class APIEditorActivity extends BaseActivity implements OnCheckedChangeLi
mAdapter = new CustomAPIConfigArrayAdapter(context, configs);
final AlertDialogWrapper.Builder builder = new AlertDialogWrapper.Builder(context);
builder.setAdapter(mAdapter, this);
getLoaderManager().initLoader(0, null, this);
if (!BuildConfig.DEBUG) {
getLoaderManager().initLoader(0, null, this);
}
return builder.create();
}

View File

@ -215,6 +215,7 @@ public class BrowserSignInActivity extends BaseActivity {
private final String mConsumerKey, mConsumerSecret;
private final BrowserSignInActivity mActivity;
private final String mAPIUrlFormat;
private final boolean mSameOAuthSigningUrl;
public GetRequestTokenTask(final BrowserSignInActivity activity) {
mActivity = activity;
@ -222,6 +223,7 @@ public class BrowserSignInActivity extends BaseActivity {
mConsumerKey = intent.getStringExtra(Accounts.CONSUMER_KEY);
mConsumerSecret = intent.getStringExtra(Accounts.CONSUMER_SECRET);
mAPIUrlFormat = intent.getStringExtra(Accounts.API_URL_FORMAT);
mSameOAuthSigningUrl = intent.getBooleanExtra(Accounts.SAME_OAUTH_SIGNING_URL, true);
}
@Override
@ -230,11 +232,12 @@ public class BrowserSignInActivity extends BaseActivity {
return SingleResponse.getInstance();
}
try {
final Endpoint endpoint = TwitterAPIFactory.getOAuthSignInEndpoint(mAPIUrlFormat, true);
final Endpoint endpoint = TwitterAPIFactory.getOAuthSignInEndpoint(mAPIUrlFormat,
mSameOAuthSigningUrl);
final Authorization auth = new OAuthAuthorization(mConsumerKey, mConsumerSecret);
final TwitterOAuth twitter = TwitterAPIFactory.getInstance(mActivity, endpoint,
final TwitterOAuth oauth = TwitterAPIFactory.getInstance(mActivity, endpoint,
auth, TwitterOAuth.class);
return SingleResponse.getInstance(twitter.getRequestToken(OAUTH_CALLBACK_OOB));
return SingleResponse.getInstance(oauth.getRequestToken(OAUTH_CALLBACK_OOB));
} catch (final TwitterException e) {
return SingleResponse.getInstance(e);
}

View File

@ -58,6 +58,9 @@ import android.widget.TextView;
import android.widget.Toast;
import com.afollestad.materialdialogs.AlertDialogWrapper;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.afollestad.materialdialogs.internal.MDButton;
import com.rengwuxian.materialedittext.MaterialEditText;
import org.mariotaku.restfu.http.Authorization;
@ -115,10 +118,10 @@ public class SignInActivity extends BaseActivity implements OnClickListener, Tex
private String mAPIUrlFormat;
private int mAuthType;
private String mConsumerKey, mConsumerSecret;
private String mUsername, mPassword;
private long mAPIChangeTimestamp;
private boolean mSameOAuthSigningUrl, mNoVersionSuffix;
private EditText mEditUsername, mEditPassword;
private View mPasswordSignInButton;
private Button mSignInButton, mSignUpButton;
private LinearLayout mSignInSignUpContainer, mUsernamePasswordContainer;
private ContentResolver mResolver;
@ -145,9 +148,7 @@ public class SignInActivity extends BaseActivity implements OnClickListener, Tex
mNoVersionSuffix = data.getBooleanExtra(Accounts.NO_VERSION_SUFFIX, false);
mConsumerKey = data.getStringExtra(Accounts.CONSUMER_KEY);
mConsumerSecret = data.getStringExtra(Accounts.CONSUMER_SECRET);
final boolean isTwipOMode = mAuthType == ParcelableCredentials.AuthType.TWIP_O_MODE;
mUsernamePasswordContainer.setVisibility(isTwipOMode ? View.GONE : View.VISIBLE);
mSignInSignUpContainer.setOrientation(isTwipOMode ? LinearLayout.VERTICAL : LinearLayout.HORIZONTAL);
updateSignInType();
}
setSignInButton();
invalidateOptionsMenu();
@ -163,6 +164,27 @@ public class SignInActivity extends BaseActivity implements OnClickListener, Tex
super.onActivityResult(requestCode, resultCode, data);
}
void updateSignInType() {
switch (mAuthType) {
case ParcelableCredentials.AuthType.XAUTH:
case ParcelableCredentials.AuthType.BASIC: {
mUsernamePasswordContainer.setVisibility(View.VISIBLE);
mSignInSignUpContainer.setOrientation(LinearLayout.HORIZONTAL);
break;
}
case ParcelableCredentials.AuthType.TWIP_O_MODE: {
mUsernamePasswordContainer.setVisibility(View.GONE);
mSignInSignUpContainer.setOrientation(LinearLayout.VERTICAL);
break;
}
default: {
mUsernamePasswordContainer.setVisibility(View.GONE);
mSignInSignUpContainer.setOrientation(LinearLayout.VERTICAL);
break;
}
}
}
@Override
public void onClick(final View v) {
switch (v.getId()) {
@ -172,13 +194,17 @@ public class SignInActivity extends BaseActivity implements OnClickListener, Tex
break;
}
case R.id.sign_in: {
if (mUsernamePasswordContainer.getVisibility() != View.VISIBLE) {
mEditUsername.setText(null);
mEditPassword.setText(null);
}
doLogin();
break;
}
case R.id.sign_in_method_introduction: {
case R.id.password_sign_in: {
final FragmentManager fm = getSupportFragmentManager();
new SignInMethodIntroductionDialogFragment().show(fm.beginTransaction(),
"sign_in_method_introduction");
PasswordSignInDialogFragment df = new PasswordSignInDialogFragment();
df.show(fm.beginTransaction(), "password_sign_in");
break;
}
}
@ -188,6 +214,7 @@ public class SignInActivity extends BaseActivity implements OnClickListener, Tex
@Override
public void onContentChanged() {
super.onContentChanged();
mPasswordSignInButton = findViewById(R.id.password_sign_in);
mEditUsername = (EditText) findViewById(R.id.username);
mEditPassword = (EditText) findViewById(R.id.password);
mSignInButton = (Button) findViewById(R.id.sign_in);
@ -239,21 +266,22 @@ public class SignInActivity extends BaseActivity implements OnClickListener, Tex
startActivityForResult(intent, REQUEST_EDIT_API);
break;
}
case R.id.open_in_browser: {
if (mAuthType != ParcelableCredentials.AuthType.OAUTH || mTask != null
&& mTask.getStatus() == AsyncTask.Status.RUNNING) return false;
saveEditedText();
final Intent intent = new Intent(this, BrowserSignInActivity.class);
intent.putExtra(Accounts.CONSUMER_KEY, mConsumerKey);
intent.putExtra(Accounts.CONSUMER_SECRET, mConsumerSecret);
intent.putExtra(Accounts.API_URL_FORMAT, mAPIUrlFormat);
startActivityForResult(intent, REQUEST_BROWSER_SIGN_IN);
break;
}
}
return super.onOptionsItemSelected(item);
}
boolean openBrowserLogin() {
if (mAuthType != ParcelableCredentials.AuthType.OAUTH || mTask != null
&& mTask.getStatus() == AsyncTask.Status.RUNNING) return true;
final Intent intent = new Intent(this, BrowserSignInActivity.class);
intent.putExtra(Accounts.CONSUMER_KEY, mConsumerKey);
intent.putExtra(Accounts.CONSUMER_SECRET, mConsumerSecret);
intent.putExtra(Accounts.API_URL_FORMAT, mAPIUrlFormat);
intent.putExtra(Accounts.SAME_OAUTH_SIGNING_URL, mSameOAuthSigningUrl);
startActivityForResult(intent, REQUEST_BROWSER_SIGN_IN);
return false;
}
@Override
public boolean onPrepareOptionsMenu(final Menu menu) {
final MenuItem itemBrowser = menu.findItem(R.id.open_in_browser);
@ -267,7 +295,6 @@ public class SignInActivity extends BaseActivity implements OnClickListener, Tex
@Override
public void onSaveInstanceState(final Bundle outState) {
saveEditedText();
setDefaultAPI();
outState.putString(Accounts.API_URL_FORMAT, mAPIUrlFormat);
outState.putInt(Accounts.AUTH_TYPE, mAuthType);
@ -275,8 +302,6 @@ public class SignInActivity extends BaseActivity implements OnClickListener, Tex
outState.putBoolean(Accounts.NO_VERSION_SUFFIX, mNoVersionSuffix);
outState.putString(Accounts.CONSUMER_KEY, mConsumerKey);
outState.putString(Accounts.CONSUMER_SECRET, mConsumerSecret);
outState.putString(Accounts.SCREEN_NAME, mUsername);
outState.putString(Accounts.PASSWORD, mPassword);
outState.putLong(EXTRA_API_LAST_CHANGE, mAPIChangeTimestamp);
super.onSaveInstanceState(outState);
}
@ -299,8 +324,6 @@ public class SignInActivity extends BaseActivity implements OnClickListener, Tex
mSameOAuthSigningUrl = savedInstanceState.getBoolean(Accounts.SAME_OAUTH_SIGNING_URL);
mConsumerKey = Utils.trim(savedInstanceState.getString(Accounts.CONSUMER_KEY));
mConsumerSecret = Utils.trim(savedInstanceState.getString(Accounts.CONSUMER_SECRET));
mUsername = savedInstanceState.getString(Accounts.SCREEN_NAME);
mPassword = savedInstanceState.getString(Accounts.PASSWORD);
mAPIChangeTimestamp = savedInstanceState.getLong(EXTRA_API_LAST_CHANGE);
}
@ -308,17 +331,17 @@ public class SignInActivity extends BaseActivity implements OnClickListener, Tex
mUsernamePasswordContainer.setVisibility(isTwipOMode ? View.GONE : View.VISIBLE);
mSignInSignUpContainer.setOrientation(isTwipOMode ? LinearLayout.VERTICAL : LinearLayout.HORIZONTAL);
mEditUsername.setText(mUsername);
mEditUsername.addTextChangedListener(this);
mEditPassword.setText(mPassword);
mEditPassword.addTextChangedListener(this);
mSignInButton.setOnClickListener(this);
mSignUpButton.setOnClickListener(this);
mPasswordSignInButton.setOnClickListener(this);
final ColorStateList color = ColorStateList.valueOf(ContextCompat.getColor(this,
R.color.material_light_green));
ViewCompat.setBackgroundTintList(mSignInButton, color);
setSignInButton();
final String consumerKey = mPreferences.getString(KEY_CONSUMER_KEY, null);
final String consumerSecret = mPreferences.getString(KEY_CONSUMER_SECRET, null);
@ -330,17 +353,24 @@ public class SignInActivity extends BaseActivity implements OnClickListener, Tex
df.show(getSupportFragmentManager(), "set_consumer_key_secret");
}
updateSignInType();
setSignInButton();
}
private void doLogin() {
if (mTask != null && mTask.getStatus() == AsyncTask.Status.RUNNING) {
mTask.cancel(true);
}
saveEditedText();
setDefaultAPI();
if (mAuthType == ParcelableCredentials.AuthType.OAUTH && mEditUsername.length() <= 0) {
openBrowserLogin();
return;
}
final OAuthToken consumerKey = TwitterAPIFactory.getOAuthToken(mConsumerKey, mConsumerSecret);
final String apiUrlFormat = TextUtils.isEmpty(mAPIUrlFormat) ? DEFAULT_TWITTER_API_URL_FORMAT : mAPIUrlFormat;
mTask = new SignInTask(this, mUsername, mPassword, mAuthType, consumerKey, apiUrlFormat,
final String username = String.valueOf(mEditUsername.getText());
final String password = String.valueOf(mEditPassword.getText());
mTask = new SignInTask(this, username, password, mAuthType, consumerKey, apiUrlFormat,
mSameOAuthSigningUrl, mNoVersionSuffix);
AsyncTaskUtils.executeTask(mTask);
}
@ -350,7 +380,6 @@ public class SignInActivity extends BaseActivity implements OnClickListener, Tex
if (mTask != null && mTask.getStatus() == AsyncTask.Status.RUNNING) {
mTask.cancel(true);
}
saveEditedText();
setDefaultAPI();
final String verifier = intent.getStringExtra(EXTRA_OAUTH_VERIFIER);
final OAuthToken consumerKey = TwitterAPIFactory.getOAuthToken(mConsumerKey, mConsumerSecret);
@ -363,12 +392,6 @@ public class SignInActivity extends BaseActivity implements OnClickListener, Tex
}
private void saveEditedText() {
if (mEditUsername == null || mEditPassword == null) return;
mUsername = ParseUtils.parseString(mEditUsername.getText());
mPassword = ParseUtils.parseString(mEditPassword.getText());
}
private void setDefaultAPI() {
final long apiLastChange = mPreferences.getLong(KEY_API_LAST_CHANGE, mAPIChangeTimestamp);
final boolean defaultApiChanged = apiLastChange != mAPIChangeTimestamp;
@ -402,8 +425,23 @@ public class SignInActivity extends BaseActivity implements OnClickListener, Tex
}
private void setSignInButton() {
mSignInButton.setEnabled(mEditPassword.getText().length() > 0 && mEditUsername.getText().length() > 0
|| mAuthType == ParcelableCredentials.AuthType.TWIP_O_MODE);
switch (mAuthType) {
case ParcelableCredentials.AuthType.XAUTH:
case ParcelableCredentials.AuthType.BASIC: {
mPasswordSignInButton.setVisibility(View.GONE);
mSignInButton.setEnabled(mEditPassword.getText().length() > 0 && mEditUsername.getText().length() > 0);
break;
}
case ParcelableCredentials.AuthType.OAUTH: {
mPasswordSignInButton.setVisibility(View.VISIBLE);
mSignInButton.setEnabled(true);
break;
}
default: {
mPasswordSignInButton.setVisibility(View.GONE);
mSignInButton.setEnabled(true);
}
}
}
void onSignInResult(final SignInResponse result) {
@ -1070,4 +1108,62 @@ public class SignInActivity extends BaseActivity implements OnClickListener, Tex
return dialog;
}
}
public static class PasswordSignInDialogFragment extends BaseSupportDialogFragment {
@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() {
@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);
SignInActivity activity = (SignInActivity) getActivity();
activity.setUsernamePassword(String.valueOf(editUsername.getText()),
String.valueOf(editPassword.getText()));
activity.doLogin();
}
});
builder.showListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
final MaterialDialog materialDialog = (MaterialDialog) dialog;
final EditText editUsername = (EditText) materialDialog.findViewById(R.id.username);
final EditText editPassword = (EditText) materialDialog.findViewById(R.id.password);
TextWatcher textWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
MDButton button = materialDialog.getActionButton(DialogAction.POSITIVE);
if (button == null) return;
button.setEnabled(editUsername.length() > 0 && editPassword.length() > 0);
}
@Override
public void afterTextChanged(Editable s) {
}
};
editUsername.addTextChangedListener(textWatcher);
editPassword.addTextChangedListener(textWatcher);
}
});
return builder.build();
}
}
private void setUsernamePassword(String username, String password) {
mEditUsername.setText(username);
mEditPassword.setText(password);
}
}

View File

@ -131,8 +131,9 @@ public class MediaTimelineLoader extends TwitterAPIStatusesLoader {
@Override
protected boolean shouldFilterStatus(final SQLiteDatabase database, final ParcelableStatus status) {
final UserKey retweetUserId = status.is_retweet ? status.user_key : null;
return !isMyTimeline() && InternalTwitterContentUtils.isFiltered(database, retweetUserId, status.text_plain,
status.spans, status.source, null, status.quoted_user_key);
return !isMyTimeline() && InternalTwitterContentUtils.isFiltered(database, retweetUserId,
status.text_plain, status.quoted_text_plain, status.spans, status.quoted_spans,
status.source, status.quoted_source, null, status.quoted_user_key);
}
private boolean isMyTimeline() {

View File

@ -57,6 +57,7 @@ public class RetweetsOfMeLoader extends TwitterAPIStatusesLoader {
@Override
protected boolean shouldFilterStatus(final SQLiteDatabase database, final ParcelableStatus status) {
return InternalTwitterContentUtils.isFiltered(database, null, status.text_plain,
status.spans, status.source, status.retweeted_by_user_key, status.quoted_user_key);
status.quoted_text_plain, status.spans, status.quoted_spans, status.source,
status.quoted_source, status.retweeted_by_user_key, status.quoted_user_key);
}
}

View File

@ -77,6 +77,7 @@ public class UserTimelineLoader extends TwitterAPIStatusesLoader {
return false;
final UserKey retweetUserId = status.is_retweet ? status.user_key : null;
return InternalTwitterContentUtils.isFiltered(database, retweetUserId, status.text_plain,
status.spans, status.source, null, status.quoted_user_key);
status.quoted_text_plain, status.spans, status.quoted_spans, status.source,
status.quoted_source, null, status.quoted_user_key);
}
}

View File

@ -122,6 +122,7 @@ import org.mariotaku.twidere.util.ActivityTracker;
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
import org.mariotaku.twidere.util.DataStoreUtils;
import org.mariotaku.twidere.util.ImagePreloader;
import org.mariotaku.twidere.util.InternalTwitterContentUtils;
import org.mariotaku.twidere.util.JsonSerializer;
import org.mariotaku.twidere.util.NotificationManagerWrapper;
import org.mariotaku.twidere.util.ParseUtils;
@ -1369,6 +1370,7 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
private void showInteractionsNotification(AccountPreferences pref, long position, boolean combined) {
final Context context = getContext();
if (context == null) return;
final SQLiteDatabase db = mDatabaseWrapper.getSQLiteDatabase();
final UserKey accountKey = pref.getAccountKey();
final String where = Expression.and(
Expression.equalsArgs(AccountSupportColumns.ACCOUNT_KEY),
@ -1408,6 +1410,14 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
activity.action)) {
continue;
}
if (activity.status_id != null && InternalTwitterContentUtils.isFiltered(db,
activity.status_user_key, activity.status_text_plain,
activity.status_quote_text_plain, activity.status_spans,
activity.status_quote_spans, activity.status_source,
activity.status_quote_source, activity.status_retweeted_by_user_key,
activity.status_quoted_user_key)) {
continue;
}
final String[] filteredUserIds = DataStoreUtils.getFilteredUserIds(context);
if (timestamp == -1) {
timestamp = activity.timestamp;

View File

@ -85,17 +85,20 @@ public class InternalTwitterContentUtils {
}
public static boolean isFiltered(final SQLiteDatabase database, final UserKey userKey,
final String textPlain, final SpanItem[] spans,
final String source, final UserKey retweetedById,
final UserKey quotedUserId) {
return isFiltered(database, userKey, textPlain, spans, source, retweetedById,
quotedUserId, true);
final String textPlain, final String quotedTextPlain,
final SpanItem[] spans, final SpanItem[] quotedSpans,
final String source, final String quotedSource,
final UserKey retweetedById, final UserKey quotedUserId) {
return isFiltered(database, userKey, textPlain, quotedTextPlain, spans, quotedSpans, source,
quotedSource, retweetedById, quotedUserId, true);
}
public static boolean isFiltered(final SQLiteDatabase database, final UserKey userKey,
final String textPlain, final SpanItem[] spans,
final String source, final UserKey retweetedById,
final UserKey quotedUserId, final boolean filterRts) {
final String textPlain, final String quotedTextPlain,
final SpanItem[] spans, final SpanItem[] quotedSpans,
final String source, final String quotedSource,
final UserKey retweetedByKey, final UserKey quotedUserKey,
final boolean filterRts) {
if (database == null) return false;
if (textPlain == null && spans == null && userKey == null && source == null)
return false;
@ -104,50 +107,61 @@ public class InternalTwitterContentUtils {
builder.append("SELECT ");
if (textPlain != null) {
selectionArgs.add(textPlain);
builder.append("(SELECT 1 IN (SELECT ? LIKE '%'||" + Filters.Keywords.TABLE_NAME + "." + Filters.VALUE
+ "||'%' FROM " + Filters.Keywords.TABLE_NAME + "))");
addTextPlainStatement(builder);
}
if (quotedTextPlain != null) {
if (!selectionArgs.isEmpty()) {
builder.append(" OR ");
}
selectionArgs.add(quotedTextPlain);
addTextPlainStatement(builder);
}
if (spans != null) {
if (!selectionArgs.isEmpty()) {
builder.append(" OR ");
}
StringBuilder spansFlat = new StringBuilder();
for (SpanItem span : spans) {
spansFlat.append(span.link);
spansFlat.append(' ');
addSpansStatement(spans, builder, selectionArgs);
}
if (quotedSpans != null) {
if (!selectionArgs.isEmpty()) {
builder.append(" OR ");
}
selectionArgs.add(spansFlat.toString());
builder.append("(SELECT 1 IN (SELECT ? LIKE '%'||" + Filters.Links.TABLE_NAME + "."
+ Filters.VALUE + "||'%' FROM " + Filters.Links.TABLE_NAME + "))");
addSpansStatement(quotedSpans, builder, selectionArgs);
}
if (userKey != null) {
if (!selectionArgs.isEmpty()) {
builder.append(" OR ");
}
selectionArgs.add(String.valueOf(userKey));
builder.append("(SELECT ").append("?").append(" IN (SELECT ").append(Filters.Users.USER_KEY).append(" FROM ").append(Filters.Users.TABLE_NAME).append("))");
createUserKeyStatement(builder);
}
if (retweetedById != null) {
if (retweetedByKey != null) {
if (!selectionArgs.isEmpty()) {
builder.append(" OR ");
}
selectionArgs.add(String.valueOf(retweetedById));
builder.append("(SELECT ").append("?").append(" IN (SELECT ").append(Filters.Users.USER_KEY).append(" FROM ").append(Filters.Users.TABLE_NAME).append("))");
selectionArgs.add(String.valueOf(retweetedByKey));
createUserKeyStatement(builder);
}
if (quotedUserId != null) {
if (quotedUserKey != null) {
if (!selectionArgs.isEmpty()) {
builder.append(" OR ");
}
selectionArgs.add(String.valueOf(quotedUserId));
builder.append("(SELECT ").append("?").append(" IN (SELECT ").append(Filters.Users.USER_KEY).append(" FROM ").append(Filters.Users.TABLE_NAME).append("))");
selectionArgs.add(String.valueOf(quotedUserKey));
createUserKeyStatement(builder);
}
if (source != null) {
if (!selectionArgs.isEmpty()) {
builder.append(" OR ");
}
selectionArgs.add(source);
builder.append("(SELECT 1 IN (SELECT ? LIKE '%>'||" + Filters.Sources.TABLE_NAME + "." + Filters.VALUE
+ "||'</a>%' FROM " + Filters.Sources.TABLE_NAME + "))");
appendSourceStatement(builder);
}
if (quotedSource != null) {
if (!selectionArgs.isEmpty()) {
builder.append(" OR ");
}
selectionArgs.add(quotedSource);
appendSourceStatement(builder);
}
final Cursor cur = database.rawQuery(builder.toString(),
selectionArgs.toArray(new String[selectionArgs.size()]));
@ -159,10 +173,43 @@ public class InternalTwitterContentUtils {
}
}
static void addTextPlainStatement(StringBuilder builder) {
builder.append("(SELECT 1 IN (SELECT ? LIKE '%'||").append(Filters.Keywords.TABLE_NAME).append(".").append(Filters.VALUE).append("||'%' FROM ").append(Filters.Keywords.TABLE_NAME).append("))");
}
static void addSpansStatement(SpanItem[] spans, StringBuilder builder, List<String> selectionArgs) {
StringBuilder spansFlat = new StringBuilder();
for (SpanItem span : spans) {
spansFlat.append(span.link);
spansFlat.append(' ');
}
selectionArgs.add(spansFlat.toString());
builder.append("(SELECT 1 IN (SELECT ? LIKE '%'||")
.append(Filters.Links.TABLE_NAME)
.append(".")
.append(Filters.VALUE)
.append("||'%' FROM ")
.append(Filters.Links.TABLE_NAME)
.append("))");
}
static void createUserKeyStatement(StringBuilder builder) {
builder.append("(SELECT ").append("?").append(" IN (SELECT ").append(Filters.Users.USER_KEY).append(" FROM ").append(Filters.Users.TABLE_NAME).append("))");
}
static void appendSourceStatement(StringBuilder builder) {
builder.append("(SELECT 1 IN (SELECT ? LIKE '%>'||")
.append(Filters.Sources.TABLE_NAME).append(".")
.append(Filters.VALUE).append("||'</a>%' FROM ")
.append(Filters.Sources.TABLE_NAME)
.append("))");
}
public static boolean isFiltered(final SQLiteDatabase database, final ParcelableStatus status,
final boolean filterRTs) {
if (database == null || status == null) return false;
return isFiltered(database, status.user_key, status.text_plain, status.spans, status.source,
return isFiltered(database, status.user_key, status.text_plain, status.quoted_text_plain,
status.spans, status.quoted_spans, status.source, status.quoted_source,
status.retweeted_by_user_key, status.quoted_user_key, filterRTs);
}

View File

@ -42,7 +42,6 @@
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="@string/username"
android:inputType="textEmailAddress"
android:singleLine="true"
@ -53,7 +52,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:ems="10"
android:hint="@string/password"
android:inputType="textPassword"
android:singleLine="true"
@ -84,14 +82,13 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:minHeight="@dimen/element_size_normal"
android:onClick="onClick"
android:text="@string/sign_in"
app:backgroundTint="@color/material_light_green"/>
</LinearLayout>
<Button
android:id="@+id/sign_in_method_introduction"
android:id="@+id/password_sign_in"
style="?android:borderlessButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -99,8 +96,7 @@
android:clickable="true"
android:gravity="center_vertical"
android:minHeight="36dp"
android:onClick="onClick"
android:text="@string/sign_in_method_introduction_title"
android:text="@string/password_sign_in_twitter_only"
android:textAppearance="?android:textAppearanceSmall"/>
</LinearLayout>
</ScrollView>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/username"
android:inputType="textEmailAddress"
android:singleLine="true"
android:typeface="normal"/>
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/element_spacing_normal"
android:hint="@string/password"
android:inputType="textPassword"
android:singleLine="true"
android:typeface="normal"/>
</LinearLayout>

View File

@ -1,17 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<item
android:id="@id/open_in_browser"
android:icon="@drawable/ic_action_web"
android:title="@string/browser_sign_in"
app:showAsAction="always"/>
<item
android:id="@id/edit_api"
android:icon="@drawable/ic_action_server"
android:title="@string/edit_api"
app:showAsAction="always"/>
app:showAsAction="always"
tools:ignore="AlwaysShowAction"/>
<item
android:id="@id/settings"
android:icon="@drawable/ic_action_settings"

View File

@ -795,4 +795,5 @@
<string name="location_countrywide">Countrywide</string>
<string name="error_title_device_incompatible">Incompatible device</string>
<string name="error_message_device_incompatible">This device is not compatible with Twidere, upgrade to latest Android OS is recommended.\nYou can send information below to help me report this issue to device manufacturer.</string>
<string name="password_sign_in_twitter_only">Password sign in (Twitter only)</string>
</resources>