diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/APIEditorActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/APIEditorActivity.java index a647de27b..5fe4f70f5 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/APIEditorActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/APIEditorActivity.java @@ -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(); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/BrowserSignInActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/BrowserSignInActivity.java index c173c9a92..0df914ee4 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/BrowserSignInActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/BrowserSignInActivity.java @@ -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); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/activity/SignInActivity.java b/twidere/src/main/java/org/mariotaku/twidere/activity/SignInActivity.java index eca4066b7..90584480e 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/activity/SignInActivity.java +++ b/twidere/src/main/java/org/mariotaku/twidere/activity/SignInActivity.java @@ -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); + } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/loader/MediaTimelineLoader.java b/twidere/src/main/java/org/mariotaku/twidere/loader/MediaTimelineLoader.java index 85084423b..895dce053 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/loader/MediaTimelineLoader.java +++ b/twidere/src/main/java/org/mariotaku/twidere/loader/MediaTimelineLoader.java @@ -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() { diff --git a/twidere/src/main/java/org/mariotaku/twidere/loader/RetweetsOfMeLoader.java b/twidere/src/main/java/org/mariotaku/twidere/loader/RetweetsOfMeLoader.java index 65aea3d33..56c5ed428 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/loader/RetweetsOfMeLoader.java +++ b/twidere/src/main/java/org/mariotaku/twidere/loader/RetweetsOfMeLoader.java @@ -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); } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/loader/UserTimelineLoader.java b/twidere/src/main/java/org/mariotaku/twidere/loader/UserTimelineLoader.java index 5e5e8a0b8..31a91df34 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/loader/UserTimelineLoader.java +++ b/twidere/src/main/java/org/mariotaku/twidere/loader/UserTimelineLoader.java @@ -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); } } diff --git a/twidere/src/main/java/org/mariotaku/twidere/provider/TwidereDataProvider.java b/twidere/src/main/java/org/mariotaku/twidere/provider/TwidereDataProvider.java index 525a5bf74..45af59d5d 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/provider/TwidereDataProvider.java +++ b/twidere/src/main/java/org/mariotaku/twidere/provider/TwidereDataProvider.java @@ -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; diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/InternalTwitterContentUtils.java b/twidere/src/main/java/org/mariotaku/twidere/util/InternalTwitterContentUtils.java index 387d87f1a..baa2bcc76 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/InternalTwitterContentUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/InternalTwitterContentUtils.java @@ -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 - + "||'%' 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 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("||'%' 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); } diff --git a/twidere/src/main/res/layout/activity_sign_in.xml b/twidere/src/main/res/layout/activity_sign_in.xml index 29fae208f..ab0b0891e 100644 --- a/twidere/src/main/res/layout/activity_sign_in.xml +++ b/twidere/src/main/res/layout/activity_sign_in.xml @@ -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"/>