improved auto complete, A LOT
This commit is contained in:
parent
a10b83eb01
commit
75c21cdf51
|
@ -270,6 +270,8 @@ public interface TwidereDataStore {
|
|||
|
||||
String LAST_SEEN = "last_seen";
|
||||
|
||||
String SCORE = "score";
|
||||
|
||||
String[] COLUMNS = {_ID, USER_ID, CREATED_AT, NAME, SCREEN_NAME,
|
||||
DESCRIPTION_PLAIN, LOCATION, URL, PROFILE_IMAGE_URL, PROFILE_BANNER_URL, IS_PROTECTED,
|
||||
IS_VERIFIED, IS_FOLLOWING, FOLLOWERS_COUNT, FRIENDS_COUNT, STATUSES_COUNT, FAVORITES_COUNT,
|
||||
|
@ -293,6 +295,7 @@ public interface TwidereDataStore {
|
|||
String ICON = "icon";
|
||||
String EXTRA_ID = "extra_id";
|
||||
String EXTRA = "extra";
|
||||
String VALUE = "value";
|
||||
|
||||
String TABLE_NAME = "suggestions";
|
||||
|
||||
|
@ -300,9 +303,9 @@ public interface TwidereDataStore {
|
|||
|
||||
Uri CONTENT_URI = Uri.withAppendedPath(BASE_CONTENT_URI, CONTENT_PATH);
|
||||
|
||||
String[] COLUMNS = {_ID, TYPE, TITLE, SUMMARY, ICON, EXTRA_ID, EXTRA};
|
||||
String[] COLUMNS = {_ID, TYPE, TITLE, SUMMARY, ICON, EXTRA_ID, EXTRA, VALUE};
|
||||
String[] TYPES = {TYPE_PRIMARY_KEY, TYPE_TEXT_NOT_NULL, TYPE_TEXT, TYPE_TEXT, TYPE_TEXT,
|
||||
TYPE_INT, TYPE_TEXT};
|
||||
TYPE_INT, TYPE_TEXT, TYPE_TEXT};
|
||||
|
||||
interface AutoComplete extends Suggestions {
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ import android.widget.ListView;
|
|||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.SimpleParcelableUserListsAdapter;
|
||||
import org.mariotaku.twidere.adapter.SimpleParcelableUsersAdapter;
|
||||
import org.mariotaku.twidere.adapter.UserHashtagAutoCompleteAdapter;
|
||||
import org.mariotaku.twidere.adapter.UserAutoCompleteAdapter;
|
||||
import org.mariotaku.twidere.api.twitter.Twitter;
|
||||
import org.mariotaku.twidere.api.twitter.TwitterException;
|
||||
import org.mariotaku.twidere.api.twitter.http.HttpResponseCode;
|
||||
|
@ -169,7 +169,7 @@ public class UserListSelectorActivity extends BaseSupportDialogActivity implemen
|
|||
getUserLists(mScreenName);
|
||||
}
|
||||
}
|
||||
final UserHashtagAutoCompleteAdapter adapter = new UserHashtagAutoCompleteAdapter(this);
|
||||
final UserAutoCompleteAdapter adapter = new UserAutoCompleteAdapter(this);
|
||||
adapter.setAccountId(getAccountId());
|
||||
mEditScreenName.setAdapter(adapter);
|
||||
mEditScreenName.setText(mScreenName);
|
||||
|
|
|
@ -29,6 +29,7 @@ import android.view.View;
|
|||
import android.widget.FilterQueryProvider;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Suggestions;
|
||||
|
@ -42,7 +43,7 @@ import org.mariotaku.twidere.view.ProfileImageView;
|
|||
import javax.inject.Inject;
|
||||
|
||||
|
||||
public class UserHashtagAutoCompleteAdapter extends SimpleCursorAdapter implements Constants {
|
||||
public class ComposeAutoCompleteAdapter extends SimpleCursorAdapter implements Constants {
|
||||
|
||||
private static final String[] FROM = new String[0];
|
||||
private static final int[] TO = new int[0];
|
||||
|
@ -56,11 +57,11 @@ public class UserHashtagAutoCompleteAdapter extends SimpleCursorAdapter implemen
|
|||
|
||||
private final boolean mDisplayProfileImage;
|
||||
|
||||
private int mTypeIdx, mIconIdx, mTitleIdx, mSummaryIdx, mExtraIdIdx;
|
||||
private int mTypeIdx, mIconIdx, mTitleIdx, mSummaryIdx, mExtraIdIdx, mValueIdx;
|
||||
private long mAccountId;
|
||||
private char mToken;
|
||||
|
||||
public UserHashtagAutoCompleteAdapter(final Context context) {
|
||||
public ComposeAutoCompleteAdapter(final Context context) {
|
||||
super(context, R.layout.list_item_auto_complete, null, FROM, TO, 0);
|
||||
DaggerGeneralComponent.builder().applicationModule(ApplicationModule.get(context)).build().inject(this);
|
||||
mDisplayProfileImage = mPreferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE, true);
|
||||
|
@ -68,7 +69,6 @@ public class UserHashtagAutoCompleteAdapter extends SimpleCursorAdapter implemen
|
|||
|
||||
@Override
|
||||
public void bindView(final View view, final Context context, final Cursor cursor) {
|
||||
if (isCursorClosed()) return;
|
||||
final TextView text1 = (TextView) view.findViewById(android.R.id.text1);
|
||||
final TextView text2 = (TextView) view.findViewById(android.R.id.text2);
|
||||
final ProfileImageView icon = (ProfileImageView) view.findViewById(android.R.id.icon);
|
||||
|
@ -78,7 +78,7 @@ public class UserHashtagAutoCompleteAdapter extends SimpleCursorAdapter implemen
|
|||
|
||||
if (Suggestions.AutoComplete.TYPE_USERS.equals(cursor.getString(mTypeIdx))) {
|
||||
text1.setText(mUserColorNameManager.getUserNickname(cursor.getLong(mExtraIdIdx), cursor.getString(mTitleIdx)));
|
||||
text2.setText("@" + cursor.getString(mSummaryIdx));
|
||||
text2.setText('@' + cursor.getString(mSummaryIdx));
|
||||
if (mDisplayProfileImage) {
|
||||
final String profileImageUrl = cursor.getString(mIconIdx);
|
||||
mProfileImageLoader.displayProfileImage(icon, profileImageUrl);
|
||||
|
@ -88,7 +88,7 @@ public class UserHashtagAutoCompleteAdapter extends SimpleCursorAdapter implemen
|
|||
|
||||
icon.clearColorFilter();
|
||||
} else {
|
||||
text1.setText("#" + cursor.getString(mTitleIdx));
|
||||
text1.setText('#' + cursor.getString(mTitleIdx));
|
||||
text2.setText(R.string.hashtag);
|
||||
|
||||
icon.setImageResource(R.drawable.ic_action_hashtag);
|
||||
|
@ -99,7 +99,7 @@ public class UserHashtagAutoCompleteAdapter extends SimpleCursorAdapter implemen
|
|||
}
|
||||
|
||||
public void closeCursor() {
|
||||
final Cursor cursor = getCursor();
|
||||
final Cursor cursor = swapCursor(null);
|
||||
if (cursor == null) return;
|
||||
if (!cursor.isClosed()) {
|
||||
cursor.close();
|
||||
|
@ -108,13 +108,15 @@ public class UserHashtagAutoCompleteAdapter extends SimpleCursorAdapter implemen
|
|||
|
||||
@Override
|
||||
public CharSequence convertToString(final Cursor cursor) {
|
||||
if (isCursorClosed()) return null;
|
||||
return cursor.getString(mSummaryIdx != -1 ? mSummaryIdx : mTitleIdx);
|
||||
switch (StringUtils.defaultIfEmpty(cursor.getString(mTypeIdx), "")) {
|
||||
case Suggestions.AutoComplete.TYPE_HASHTAGS: {
|
||||
return '#' + cursor.getString(mValueIdx);
|
||||
}
|
||||
|
||||
public boolean isCursorClosed() {
|
||||
final Cursor cursor = getCursor();
|
||||
return cursor == null || cursor.isClosed();
|
||||
case Suggestions.AutoComplete.TYPE_USERS: {
|
||||
return '@' + cursor.getString(mValueIdx);
|
||||
}
|
||||
}
|
||||
return cursor.getString(mValueIdx);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -159,6 +161,7 @@ public class UserHashtagAutoCompleteAdapter extends SimpleCursorAdapter implemen
|
|||
mSummaryIdx = cursor.getColumnIndex(Suggestions.AutoComplete.SUMMARY);
|
||||
mExtraIdIdx = cursor.getColumnIndex(Suggestions.AutoComplete.EXTRA_ID);
|
||||
mIconIdx = cursor.getColumnIndex(Suggestions.AutoComplete.ICON);
|
||||
mValueIdx = cursor.getColumnIndex(Suggestions.AutoComplete.VALUE);
|
||||
}
|
||||
return super.swapCursor(cursor);
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.support.v4.widget.SimpleCursorAdapter;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.widget.FilterQueryProvider;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.mariotaku.sqliteqb.library.Columns;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.sqliteqb.library.OrderBy;
|
||||
import org.mariotaku.sqliteqb.library.RawItemArray;
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers;
|
||||
import org.mariotaku.twidere.util.MediaLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.SharedPreferencesWrapper;
|
||||
import org.mariotaku.twidere.util.UserColorNameManager;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.util.dagger.ApplicationModule;
|
||||
import org.mariotaku.twidere.util.dagger.DaggerGeneralComponent;
|
||||
import org.mariotaku.twidere.view.ProfileImageView;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
|
||||
public class UserAutoCompleteAdapter extends SimpleCursorAdapter implements Constants {
|
||||
|
||||
private static final String[] FROM = new String[0];
|
||||
private static final int[] TO = new int[0];
|
||||
|
||||
@Inject
|
||||
MediaLoaderWrapper mProfileImageLoader;
|
||||
@Inject
|
||||
SharedPreferencesWrapper mPreferences;
|
||||
@Inject
|
||||
UserColorNameManager mUserColorNameManager;
|
||||
|
||||
private final boolean mDisplayProfileImage;
|
||||
|
||||
private int mIdIdx, mNameIdx, mScreenNameIdx, mProfileImageIdx;
|
||||
private long mAccountId;
|
||||
private char mToken;
|
||||
|
||||
public UserAutoCompleteAdapter(final Context context) {
|
||||
super(context, R.layout.list_item_auto_complete, null, FROM, TO, 0);
|
||||
DaggerGeneralComponent.builder().applicationModule(ApplicationModule.get(context)).build().inject(this);
|
||||
mDisplayProfileImage = mPreferences.getBoolean(KEY_DISPLAY_PROFILE_IMAGE, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindView(final View view, final Context context, final Cursor cursor) {
|
||||
final TextView text1 = (TextView) view.findViewById(android.R.id.text1);
|
||||
final TextView text2 = (TextView) view.findViewById(android.R.id.text2);
|
||||
final ProfileImageView icon = (ProfileImageView) view.findViewById(android.R.id.icon);
|
||||
|
||||
// Clear images in order to prevent images in recycled view shown.
|
||||
icon.setImageDrawable(null);
|
||||
|
||||
text1.setText(mUserColorNameManager.getUserNickname(cursor.getLong(mIdIdx), cursor.getString(mNameIdx)));
|
||||
text2.setText('@' + cursor.getString(mScreenNameIdx));
|
||||
if (mDisplayProfileImage) {
|
||||
final String profileImageUrl = cursor.getString(mProfileImageIdx);
|
||||
mProfileImageLoader.displayProfileImage(icon, profileImageUrl);
|
||||
} else {
|
||||
mProfileImageLoader.cancelDisplayTask(icon);
|
||||
}
|
||||
|
||||
icon.setVisibility(mDisplayProfileImage ? View.VISIBLE : View.GONE);
|
||||
super.bindView(view, context, cursor);
|
||||
}
|
||||
|
||||
public void closeCursor() {
|
||||
final Cursor cursor = swapCursor(null);
|
||||
if (cursor == null) return;
|
||||
if (!cursor.isClosed()) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence convertToString(final Cursor cursor) {
|
||||
return cursor.getString(mScreenNameIdx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor runQueryOnBackgroundThread(final CharSequence constraint) {
|
||||
if (TextUtils.isEmpty(constraint)) return null;
|
||||
final FilterQueryProvider filter = getFilterQueryProvider();
|
||||
if (filter != null) return filter.runQuery(constraint);
|
||||
final String query = constraint.toString();
|
||||
final String queryEscaped = query.replace("_", "^_");
|
||||
final long[] nicknameIds = Utils.getMatchedNicknameIds(query, mUserColorNameManager);
|
||||
final Expression usersSelection = Expression.or(
|
||||
Expression.likeRaw(new Columns.Column(CachedUsers.SCREEN_NAME), "?||'%'", "^"),
|
||||
Expression.likeRaw(new Columns.Column(CachedUsers.NAME), "?||'%'", "^"),
|
||||
Expression.in(new Columns.Column(CachedUsers.USER_ID), new RawItemArray(nicknameIds)));
|
||||
final String[] selectionArgs = new String[]{queryEscaped, queryEscaped};
|
||||
final String[] order = {CachedUsers.LAST_SEEN, CachedUsers.SCORE, CachedUsers.SCREEN_NAME,
|
||||
CachedUsers.NAME};
|
||||
final boolean[] ascending = {false, false, true, true};
|
||||
final OrderBy orderBy = new OrderBy(order, ascending);
|
||||
final Uri uri = Uri.withAppendedPath(CachedUsers.CONTENT_URI_WITH_SCORE, String.valueOf(mAccountId));
|
||||
return mContext.getContentResolver().query(uri, CachedUsers.COLUMNS, usersSelection.getSQL(),
|
||||
selectionArgs, orderBy.getSQL());
|
||||
}
|
||||
|
||||
|
||||
public void setAccountId(long accountId) {
|
||||
mAccountId = accountId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor swapCursor(final Cursor cursor) {
|
||||
if (cursor != null) {
|
||||
mIdIdx = cursor.getColumnIndex(CachedUsers.USER_ID);
|
||||
mNameIdx = cursor.getColumnIndex(CachedUsers.NAME);
|
||||
mScreenNameIdx = cursor.getColumnIndex(CachedUsers.SCREEN_NAME);
|
||||
mProfileImageIdx = cursor.getColumnIndex(CachedUsers.PROFILE_IMAGE_URL);
|
||||
}
|
||||
return super.swapCursor(cursor);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -59,8 +59,8 @@ import org.mariotaku.sqliteqb.library.Expression;
|
|||
import org.mariotaku.sqliteqb.library.RawItemArray;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.activity.support.UserListSelectorActivity;
|
||||
import org.mariotaku.twidere.adapter.ComposeAutoCompleteAdapter;
|
||||
import org.mariotaku.twidere.adapter.SourceAutoCompleteAdapter;
|
||||
import org.mariotaku.twidere.adapter.UserHashtagAutoCompleteAdapter;
|
||||
import org.mariotaku.twidere.fragment.support.AbsContentListViewFragment;
|
||||
import org.mariotaku.twidere.fragment.support.BaseSupportDialogFragment;
|
||||
import org.mariotaku.twidere.model.ParcelableUser;
|
||||
|
@ -292,7 +292,7 @@ public abstract class BaseFiltersFragment extends AbsContentListViewFragment<Sim
|
|||
if (auto_complete_type == AUTO_COMPLETE_TYPE_SOURCES) {
|
||||
mUserAutoCompleteAdapter = new SourceAutoCompleteAdapter(activity);
|
||||
} else {
|
||||
final UserHashtagAutoCompleteAdapter adapter = new UserHashtagAutoCompleteAdapter(activity);
|
||||
final ComposeAutoCompleteAdapter adapter = new ComposeAutoCompleteAdapter(activity);
|
||||
adapter.setAccountId(Utils.getDefaultAccountId(activity));
|
||||
mUserAutoCompleteAdapter = adapter;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ import android.view.View;
|
|||
import android.widget.AutoCompleteTextView;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.UserHashtagAutoCompleteAdapter;
|
||||
import org.mariotaku.twidere.adapter.ComposeAutoCompleteAdapter;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
import org.mariotaku.twidere.util.ParseUtils;
|
||||
import org.mariotaku.twidere.util.ThemeUtils;
|
||||
|
@ -42,7 +42,7 @@ public class AddUserListMemberDialogFragment extends BaseSupportDialogFragment i
|
|||
|
||||
public static final String FRAGMENT_TAG = "add_user_list_member";
|
||||
private AutoCompleteTextView mEditText;
|
||||
private UserHashtagAutoCompleteAdapter mUserAutoCompleteAdapter;
|
||||
private ComposeAutoCompleteAdapter mUserAutoCompleteAdapter;
|
||||
|
||||
@Override
|
||||
public void onClick(final DialogInterface dialog, final int which) {
|
||||
|
@ -71,7 +71,7 @@ public class AddUserListMemberDialogFragment extends BaseSupportDialogFragment i
|
|||
if (savedInstanceState != null) {
|
||||
mEditText.setText(savedInstanceState.getCharSequence(EXTRA_TEXT));
|
||||
}
|
||||
mUserAutoCompleteAdapter = new UserHashtagAutoCompleteAdapter(wrapped);
|
||||
mUserAutoCompleteAdapter = new ComposeAutoCompleteAdapter(wrapped);
|
||||
final Bundle args = getArguments();
|
||||
mUserAutoCompleteAdapter.setAccountId(args.getLong(EXTRA_ACCOUNT_ID));
|
||||
mEditText.setAdapter(mUserAutoCompleteAdapter);
|
||||
|
|
|
@ -49,7 +49,7 @@ import org.mariotaku.twidere.util.LinkCreator;
|
|||
import org.mariotaku.twidere.util.MenuUtils;
|
||||
import org.mariotaku.twidere.util.ThemeUtils;
|
||||
import org.mariotaku.twidere.util.TwidereValidator;
|
||||
import org.mariotaku.twidere.view.ComposeMaterialEditText;
|
||||
import org.mariotaku.twidere.view.ComposeEditText;
|
||||
import org.mariotaku.twidere.view.StatusTextCountView;
|
||||
import org.mariotaku.twidere.view.holder.StatusViewHolder;
|
||||
import org.mariotaku.twidere.view.holder.StatusViewHolder.DummyStatusHolderAdapter;
|
||||
|
@ -121,7 +121,7 @@ public class RetweetQuoteDialogFragment extends BaseSupportDialogFragment implem
|
|||
view.findViewById(R.id.action_buttons).setVisibility(View.GONE);
|
||||
view.findViewById(R.id.item_content).setFocusable(false);
|
||||
view.findViewById(R.id.comment_container).setVisibility(status.user_is_protected ? View.GONE : View.VISIBLE);
|
||||
final ComposeMaterialEditText mEditComment = (ComposeMaterialEditText) view.findViewById(R.id.edit_comment);
|
||||
final ComposeEditText mEditComment = (ComposeEditText) view.findViewById(R.id.edit_comment);
|
||||
mEditComment.setAccountId(status.account_id);
|
||||
|
||||
final boolean sendByEnter = mPreferences.getBoolean(KEY_QUICK_SEND);
|
||||
|
|
|
@ -780,7 +780,8 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
|
|||
new Column(SQLConstants.NULL, Suggestions.Search.SUMMARY).getSQL(),
|
||||
new Column(SQLConstants.NULL, Suggestions.Search.ICON).getSQL(),
|
||||
new Column("0", Suggestions.Search.EXTRA_ID).getSQL(),
|
||||
new Column(SQLConstants.NULL, Suggestions.Search.EXTRA).getSQL()
|
||||
new Column(SQLConstants.NULL, Suggestions.Search.EXTRA).getSQL(),
|
||||
new Column(SearchHistory.QUERY, Suggestions.Search.VALUE).getSQL(),
|
||||
};
|
||||
final Expression historySelection = Expression.likeRaw(new Column(SearchHistory.QUERY), "?||'%'", "^");
|
||||
@SuppressLint("Recycle") final Cursor historyCursor = mDatabaseWrapper.query(true,
|
||||
|
@ -795,7 +796,8 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
|
|||
new Column(SQLConstants.NULL, Suggestions.Search.SUMMARY).getSQL(),
|
||||
new Column(SQLConstants.NULL, Suggestions.Search.ICON).getSQL(),
|
||||
new Column("0", Suggestions.Search.EXTRA_ID).getSQL(),
|
||||
new Column(SQLConstants.NULL, Suggestions.Search.EXTRA).getSQL()
|
||||
new Column(SQLConstants.NULL, Suggestions.Search.EXTRA).getSQL(),
|
||||
new Column(SavedSearches.QUERY, Suggestions.Search.VALUE).getSQL()
|
||||
};
|
||||
final Expression savedSearchesWhere = Expression.equals(SavedSearches.ACCOUNT_ID, accountId);
|
||||
@SuppressLint("Recycle") final Cursor savedSearchesCursor = mDatabaseWrapper.query(true,
|
||||
|
@ -811,7 +813,8 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
|
|||
new Column(CachedUsers.SCREEN_NAME, Suggestions.Search.SUMMARY).getSQL(),
|
||||
new Column(CachedUsers.PROFILE_IMAGE_URL, Suggestions.Search.ICON).getSQL(),
|
||||
new Column(CachedUsers.USER_ID, Suggestions.Search.EXTRA_ID).getSQL(),
|
||||
new Column(SQLConstants.NULL, Suggestions.Search.EXTRA).getSQL()
|
||||
new Column(SQLConstants.NULL, Suggestions.Search.EXTRA).getSQL(),
|
||||
new Column(CachedUsers.SCREEN_NAME, Suggestions.Search.VALUE).getSQL(),
|
||||
};
|
||||
String queryTrimmed = queryEscaped.startsWith("@") ? queryEscaped.substring(1) : queryEscaped;
|
||||
final long[] nicknameIds = Utils.getMatchedNicknameIds(query, mUserColorNameManager);
|
||||
|
@ -820,7 +823,8 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
|
|||
Expression.likeRaw(new Column(CachedUsers.NAME), "?||'%'", "^"),
|
||||
Expression.in(new Column(CachedUsers.USER_ID), new RawItemArray(nicknameIds)));
|
||||
final String[] selectionArgs = new String[]{queryTrimmed, queryTrimmed};
|
||||
final String[] order = {CachedUsers.LAST_SEEN, "score", CachedUsers.SCREEN_NAME, CachedUsers.NAME};
|
||||
final String[] order = {CachedUsers.LAST_SEEN, CachedUsers.SCORE, CachedUsers.SCREEN_NAME,
|
||||
CachedUsers.NAME};
|
||||
final boolean[] ascending = {false, false, true, true};
|
||||
final OrderBy orderBy = new OrderBy(order, ascending);
|
||||
|
||||
|
@ -838,7 +842,7 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
|
|||
final Matcher m = PATTERN_SCREEN_NAME.matcher(query);
|
||||
if (m.matches()) {
|
||||
screenNameCursor.addRow(new Object[]{0, Suggestions.Search.TYPE_SCREEN_NAME,
|
||||
query, null, null, 0, null});
|
||||
query, null, null, 0, null, query});
|
||||
}
|
||||
}
|
||||
cursors = new Cursor[3];
|
||||
|
@ -868,8 +872,9 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
|
|||
new Column(CachedUsers.SCREEN_NAME, Suggestions.SUMMARY).getSQL(),
|
||||
new Column(CachedUsers.USER_ID, Suggestions.EXTRA_ID).getSQL(),
|
||||
new Column(CachedUsers.PROFILE_IMAGE_URL, Suggestions.ICON).getSQL(),
|
||||
new Column(CachedUsers.SCREEN_NAME, Suggestions.VALUE).getSQL(),
|
||||
};
|
||||
final String[] orderBy = {"score", CachedUsers.LAST_SEEN, CachedUsers.SCREEN_NAME,
|
||||
final String[] orderBy = {CachedUsers.SCORE, CachedUsers.LAST_SEEN, CachedUsers.SCREEN_NAME,
|
||||
CachedUsers.NAME};
|
||||
final boolean[] ascending = {false, false, true, true};
|
||||
return query(Uri.withAppendedPath(CachedUsers.CONTENT_URI_WITH_SCORE, accountId),
|
||||
|
@ -884,6 +889,7 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
|
|||
new Column("NULL", Suggestions.SUMMARY).getSQL(),
|
||||
new Column("0", Suggestions.EXTRA_ID).getSQL(),
|
||||
new Column("NULL", Suggestions.ICON).getSQL(),
|
||||
new Column(CachedHashtags.NAME, Suggestions.VALUE).getSQL(),
|
||||
};
|
||||
return query(CachedHashtags.CONTENT_URI, mappedProjection, where.getSQL(),
|
||||
whereArgs, null);
|
||||
|
|
|
@ -29,8 +29,9 @@ import org.mariotaku.twidere.adapter.AccountsAdapter;
|
|||
import org.mariotaku.twidere.adapter.AccountsSpinnerAdapter;
|
||||
import org.mariotaku.twidere.adapter.BaseArrayAdapter;
|
||||
import org.mariotaku.twidere.adapter.BaseRecyclerViewAdapter;
|
||||
import org.mariotaku.twidere.adapter.ComposeAutoCompleteAdapter;
|
||||
import org.mariotaku.twidere.adapter.DraftsAdapter;
|
||||
import org.mariotaku.twidere.adapter.UserHashtagAutoCompleteAdapter;
|
||||
import org.mariotaku.twidere.adapter.UserAutoCompleteAdapter;
|
||||
import org.mariotaku.twidere.fragment.BaseDialogFragment;
|
||||
import org.mariotaku.twidere.fragment.BaseFiltersFragment;
|
||||
import org.mariotaku.twidere.fragment.BaseFragment;
|
||||
|
@ -86,7 +87,9 @@ public interface GeneralComponent {
|
|||
|
||||
void inject(AccountsAdapter object);
|
||||
|
||||
void inject(UserHashtagAutoCompleteAdapter object);
|
||||
void inject(ComposeAutoCompleteAdapter object);
|
||||
|
||||
void inject(UserAutoCompleteAdapter object);
|
||||
|
||||
void inject(AccountsSpinnerAdapter object);
|
||||
|
||||
|
|
|
@ -20,17 +20,25 @@
|
|||
package org.mariotaku.twidere.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.AppCompatMultiAutoCompleteTextView;
|
||||
import android.text.InputType;
|
||||
import android.text.Selection;
|
||||
import android.text.method.ArrowKeyMovementMethod;
|
||||
import android.text.method.MovementMethod;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.UserHashtagAutoCompleteAdapter;
|
||||
import org.mariotaku.twidere.adapter.ComposeAutoCompleteAdapter;
|
||||
import org.mariotaku.twidere.util.widget.StatusTextTokenizer;
|
||||
import org.mariotaku.twidere.view.iface.IThemeBackgroundTintView;
|
||||
|
||||
public class ComposeEditText extends AppCompatMultiAutoCompleteTextView {
|
||||
public class ComposeEditText extends AppCompatMultiAutoCompleteTextView implements IThemeBackgroundTintView {
|
||||
|
||||
private UserHashtagAutoCompleteAdapter mAdapter;
|
||||
private ComposeAutoCompleteAdapter mAdapter;
|
||||
private long mAccountId;
|
||||
|
||||
public ComposeEditText(final Context context) {
|
||||
|
@ -44,14 +52,36 @@ public class ComposeEditText extends AppCompatMultiAutoCompleteTextView {
|
|||
public ComposeEditText(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
setTokenizer(new StatusTextTokenizer());
|
||||
setMovementMethod(ArrowKeyMovementMethod.getInstance());
|
||||
setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
removeIMESuggestions();
|
||||
}
|
||||
});
|
||||
// HACK: remove AUTO_COMPLETE flag to force IME show auto completion
|
||||
setRawInputType(getInputType() & ~InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackgroundTintColor(@NonNull ColorStateList color) {
|
||||
setSupportBackgroundTintList(color);
|
||||
}
|
||||
|
||||
public void setAccountId(long accountId) {
|
||||
mAccountId = accountId;
|
||||
updateAccountId();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MovementMethod getDefaultMovementMethod() {
|
||||
return ArrowKeyMovementMethod.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
if (!isInEditMode() && mAdapter == null) {
|
||||
mAdapter = new UserHashtagAutoCompleteAdapter(getContext());
|
||||
mAdapter = new ComposeAutoCompleteAdapter(getContext());
|
||||
}
|
||||
setAdapter(mAdapter);
|
||||
updateAccountId();
|
||||
|
@ -66,13 +96,14 @@ public class ComposeEditText extends AppCompatMultiAutoCompleteTextView {
|
|||
}
|
||||
}
|
||||
|
||||
public void setAccountId(long accountId) {
|
||||
mAccountId = accountId;
|
||||
updateAccountId();
|
||||
}
|
||||
|
||||
private void updateAccountId() {
|
||||
if (mAdapter == null) return;
|
||||
mAdapter.setAccountId(mAccountId);
|
||||
}
|
||||
|
||||
private void removeIMESuggestions() {
|
||||
final int selectionEnd = getSelectionEnd(), selectionStart = getSelectionStart();
|
||||
Selection.removeSelection(getText());
|
||||
setSelection(selectionStart, selectionEnd);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,101 +0,0 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 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.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.AppCompatMultiAutoCompleteTextView;
|
||||
import android.text.InputType;
|
||||
import android.text.method.ArrowKeyMovementMethod;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.UserHashtagAutoCompleteAdapter;
|
||||
import org.mariotaku.twidere.util.widget.StatusTextTokenizer;
|
||||
import org.mariotaku.twidere.view.iface.IThemeBackgroundTintView;
|
||||
|
||||
public class ComposeMaterialEditText extends AppCompatMultiAutoCompleteTextView implements IThemeBackgroundTintView {
|
||||
|
||||
private UserHashtagAutoCompleteAdapter mAdapter;
|
||||
private long mAccountId;
|
||||
|
||||
public ComposeMaterialEditText(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public ComposeMaterialEditText(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, R.attr.autoCompleteTextViewStyle);
|
||||
}
|
||||
|
||||
public ComposeMaterialEditText(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
setTokenizer(new StatusTextTokenizer());
|
||||
setMovementMethod(ArrowKeyMovementMethod.getInstance());
|
||||
setupComposeInputType();
|
||||
}
|
||||
|
||||
private void setupComposeInputType() {
|
||||
int rawInputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES;
|
||||
rawInputType |= InputType.TYPE_TEXT_FLAG_MULTI_LINE;
|
||||
setRawInputType(rawInputType);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
if (!isInEditMode() && mAdapter == null) {
|
||||
mAdapter = new UserHashtagAutoCompleteAdapter(getContext());
|
||||
}
|
||||
setAdapter(mAdapter);
|
||||
updateAccountId();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
if (mAdapter != null) {
|
||||
mAdapter.closeCursor();
|
||||
mAdapter = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackgroundTintColor(@NonNull ColorStateList color) {
|
||||
setSupportBackgroundTintList(color);
|
||||
}
|
||||
|
||||
public void setAccountId(long accountId) {
|
||||
mAccountId = accountId;
|
||||
updateAccountId();
|
||||
}
|
||||
|
||||
private void updateAccountId() {
|
||||
if (mAdapter == null) return;
|
||||
mAdapter.setAccountId(mAccountId);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void replaceText(final CharSequence text) {
|
||||
super.replaceText(text);
|
||||
append(" ");
|
||||
}
|
||||
|
||||
}
|
|
@ -44,7 +44,7 @@
|
|||
android:alpha="0.2"
|
||||
android:numColumns="@integer/grid_column_image_preview"
|
||||
android:stretchMode="columnWidth"
|
||||
tools:listitem="@layout/grid_item_image_preview" />
|
||||
tools:listitem="@layout/gallery_item_image_preview" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/edit_text_container"
|
||||
|
@ -58,13 +58,13 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:background="@null"
|
||||
android:completionThreshold="1"
|
||||
android:gravity="top"
|
||||
android:hint="@string/status_hint"
|
||||
android:inputType="text|textLongMessage|textAutoComplete|textMultiLine"
|
||||
android:inputType="textMultiLine|textShortMessage"
|
||||
android:minLines="6"
|
||||
android:padding="@dimen/element_spacing_normal"
|
||||
android:scrollbars="vertical" />
|
||||
android:scrollbars="vertical"
|
||||
android:singleLine="false" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/location_container"
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<org.mariotaku.twidere.view.ComposeMaterialEditText
|
||||
<org.mariotaku.twidere.view.ComposeEditText
|
||||
android:id="@+id/edit_comment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -49,7 +49,7 @@
|
|||
android:visibility="visible">
|
||||
|
||||
<requestFocus />
|
||||
</org.mariotaku.twidere.view.ComposeMaterialEditText>
|
||||
</org.mariotaku.twidere.view.ComposeEditText>
|
||||
|
||||
<org.mariotaku.twidere.view.StatusTextCountView
|
||||
android:id="@+id/comment_text_count"
|
||||
|
|
Loading…
Reference in New Issue