Improves user search feature

This commit is contained in:
tom79 2017-08-02 17:44:36 +02:00
parent 941b877f70
commit e472f7443f
4 changed files with 217 additions and 139 deletions

View File

@ -48,15 +48,16 @@ import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.HorizontalScrollView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
@ -83,11 +84,9 @@ import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import fr.gouv.etalab.mastodon.asynctasks.PostActionAsyncTask;
import fr.gouv.etalab.mastodon.asynctasks.PostStatusAsyncTask;
import fr.gouv.etalab.mastodon.asynctasks.RetrieveSearchAccountsAsyncTask;
import fr.gouv.etalab.mastodon.asynctasks.UploadActionAsyncTask;
import fr.gouv.etalab.mastodon.client.API;
import fr.gouv.etalab.mastodon.client.APIResponse;
import fr.gouv.etalab.mastodon.client.Entities.Account;
import fr.gouv.etalab.mastodon.client.Entities.Attachment;
@ -99,7 +98,6 @@ import fr.gouv.etalab.mastodon.client.PatchBaseImageDownloader;
import fr.gouv.etalab.mastodon.drawers.AccountsSearchAdapter;
import fr.gouv.etalab.mastodon.drawers.DraftsListAdapter;
import fr.gouv.etalab.mastodon.helper.Helper;
import fr.gouv.etalab.mastodon.interfaces.OnPostActionInterface;
import fr.gouv.etalab.mastodon.interfaces.OnPostStatusActionInterface;
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveAttachmentInterface;
import fr.gouv.etalab.mastodon.interfaces.OnRetrieveSearcAccountshInterface;
@ -133,11 +131,10 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
private boolean isSensitive = false;
private ImageButton toot_visibility;
private Button toot_it;
private EditText toot_content, toot_cw_content;
private AutoCompleteTextView toot_content;
private EditText toot_cw_content;
private TextView toot_reply_content;
private RelativeLayout toot_reply_content_container;
private RelativeLayout toot_show_accounts;
private ListView toot_lv_accounts;
private BroadcastReceiver search_validate;
private Status tootReply = null;
private String sharedContent, sharedSubject;
@ -148,7 +145,8 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
private ImageView pp_actionBar;
private ProgressBar pp_progress;
private Toast mToast;
private LinearLayout drawer_layout;
private HorizontalScrollView picture_scrollview;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -208,15 +206,15 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
toot_picture = (ImageButton) findViewById(R.id.toot_picture);
loading_picture = (ProgressBar) findViewById(R.id.loading_picture);
toot_picture_container = (LinearLayout) findViewById(R.id.toot_picture_container);
toot_content = (EditText) findViewById(R.id.toot_content);
toot_content = (AutoCompleteTextView) findViewById(R.id.toot_content);
toot_cw_content = (EditText) findViewById(R.id.toot_cw_content);
toot_reply_content = (TextView) findViewById(R.id.toot_reply_content);
toot_reply_content_container = (RelativeLayout) findViewById(R.id.toot_reply_content_container);
toot_show_accounts = (RelativeLayout) findViewById(R.id.toot_show_accounts);
toot_lv_accounts = (ListView) findViewById(R.id.toot_lv_accounts);
picture_scrollview = (HorizontalScrollView) findViewById(R.id.picture_scrollview);
toot_sensitive = (CheckBox) findViewById(R.id.toot_sensitive);
//search_small_container = (LinearLayout) findViewById(R.id.search_small_container);
final LinearLayout drawer_layout = (LinearLayout) findViewById(R.id.drawer_layout);
drawer_layout = (LinearLayout) findViewById(R.id.drawer_layout);
drawer_layout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
@ -309,26 +307,23 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
toot_content.setText(newContent);
toot_content.setSelection(toot_content.getText().length());
}
toot_show_accounts.setVisibility(View.GONE);
showKeyboard();
// manageShowUsers(searchAction.CLOSE, false);
}
};
LocalBroadcastManager.getInstance(this).registerReceiver(search_validate, new IntentFilter(Helper.SEARCH_VALIDATE_ACCOUNT));
FloatingActionButton toot_close_accounts = (FloatingActionButton) findViewById(R.id.toot_close_accounts);
boolean isAccountPrivate = account.isLocked();
FloatingActionButton ic_close = (FloatingActionButton) findViewById(R.id.toot_close_reply);
toot_close_accounts.setOnClickListener(new View.OnClickListener() {
/*toot_close_accounts.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
toot_show_accounts.setVisibility(View.GONE);
showKeyboard();
manageShowUsers(searchAction.CLOSE, true);
}
});
*/
ic_close.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@ -433,7 +428,6 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
public void onTextChanged(CharSequence s, int start, int before, int count) {}
@Override
public void afterTextChanged(Editable s) {
int length;
//Only check last 20 characters to avoid lags
if( s.toString().length() < 20 ){ //Less than 20 characters are written
@ -449,9 +443,8 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
pp_actionBar.setVisibility(View.GONE);
}
new RetrieveSearchAccountsAsyncTask(getApplicationContext(),search,TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}else{
toot_show_accounts.setVisibility(View.GONE);
}
}else{toot_content.dismissDropDown();}
int totalChar = toot_cw_content.length() + toot_content.length();
int remainChar = (maxChar - totalChar);
if( remainChar >= 0){
@ -484,7 +477,6 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
return false;
}
});
toot_cw_content.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@ -530,6 +522,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE && resultCode == Activity.RESULT_OK) {
picture_scrollview.setVisibility(View.VISIBLE);
if (data == null) {
Toast.makeText(getApplicationContext(),R.string.toot_select_image_error,Toast.LENGTH_LONG).show();
return;
@ -761,25 +754,19 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
LocalBroadcastManager.getInstance(this).unregisterReceiver(search_validate);
}
@Override
public void onBackPressed() {
if( toot_show_accounts.getVisibility() == View.VISIBLE) {
toot_show_accounts.setVisibility(View.GONE);
showKeyboard();
}else
super.onBackPressed();
}
@Override
public void onRetrieveAttachment(final Attachment attachment, Error error) {
loading_picture.setVisibility(View.GONE);
toot_picture_container.setVisibility(View.VISIBLE);
if( error != null){
final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
boolean show_error_messages = sharedpreferences.getBoolean(Helper.SET_SHOW_ERROR_MESSAGES, true);
if( show_error_messages)
Toast.makeText(getApplicationContext(), error.getError(),Toast.LENGTH_LONG).show();
if( attachments.size() == 0 )
toot_picture_container.setVisibility(View.GONE);
return;
}
toot_picture_container.setVisibility(View.VISIBLE);
if( attachment != null ){
String url = attachment.getPreview_url();
if( url == null || url.trim().equals(""))
@ -804,6 +791,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
if( attachments.size() < 4)
toot_picture.setEnabled(true);
toot_sensitive.setVisibility(View.VISIBLE);
picture_scrollview.setVisibility(View.VISIBLE);
}
}
@ -839,6 +827,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
toot_sensitive.setVisibility(View.GONE);
isSensitive = false;
toot_sensitive.setChecked(false);
picture_scrollview.setVisibility(View.GONE);
}
toot_picture.setEnabled(true);
}
@ -965,11 +954,9 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
List<Account> accounts = apiResponse.getAccounts();
if( accounts != null && accounts.size() > 0){
AccountsSearchAdapter accountsListAdapter = new AccountsSearchAdapter(TootActivity.this, accounts);
toot_lv_accounts.setAdapter(accountsListAdapter);
accountsListAdapter.notifyDataSetChanged();
toot_show_accounts.setVisibility(View.VISIBLE);
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(toot_content.getWindowToken(), 0);
toot_content.showDropDown();
toot_content.setThreshold(0);
toot_content.setAdapter(accountsListAdapter);
}
}
@ -984,6 +971,7 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
loading_picture.setVisibility(View.GONE);
if( attachments != null && attachments.size() > 0){
toot_picture_container.setVisibility(View.VISIBLE);
picture_scrollview.setVisibility(View.VISIBLE);
int i = 0 ;
for(Attachment attachment: attachments){
String url = attachment.getPreview_url();
@ -1056,10 +1044,33 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc
}
}
private void showKeyboard(){
InputMethodManager inputMethodManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.toggleSoftInputFromWindow(toot_content.getApplicationWindowToken(), InputMethodManager.SHOW_FORCED, 0);
}
/*private void manageShowUsers(searchAction action, boolean click){
final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
boolean show_reply = sharedpreferences.getBoolean(Helper.SET_SHOW_REPLY, false);
Log.v(Helper.TAG,"action: " + action);
if(action == searchAction.CLOSE){
toot_show_accounts.setVisibility(View.GONE);
search_small_container.setVisibility(View.GONE);
bottom_container.setVisibility(View.VISIBLE);
if( show_reply && tootReply != null){
toot_reply_content_container.setVisibility(View.VISIBLE);
}else {
toot_reply_content_container.setVisibility(View.GONE);
}
toot_content.requestFocus();
if( !click) {
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.toggleSoftInputFromWindow(toot_content.getApplicationWindowToken(), InputMethodManager.SHOW_FORCED, 0);
}
}else if(action == searchAction.OPEN){
toot_show_accounts.setVisibility(View.VISIBLE);
search_small_container.setVisibility(View.VISIBLE);
bottom_container.setVisibility(View.GONE);
toot_reply_content_container.setVisibility(View.GONE);
}
}*/
private void tootReply(){

View File

@ -17,11 +17,14 @@ package fr.gouv.etalab.mastodon.drawers;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v4.content.LocalBroadcastManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@ -30,6 +33,7 @@ import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.display.SimpleBitmapDisplayer;
import java.util.ArrayList;
import java.util.List;
import fr.gouv.etalab.mastodon.client.Entities.Account;
import fr.gouv.etalab.mastodon.helper.Helper;
@ -40,16 +44,19 @@ import mastodon.etalab.gouv.fr.mastodon.R;
* Created by Thomas on 05/05/2017.
* Adapter for accounts when searching
*/
public class AccountsSearchAdapter extends BaseAdapter {
public class AccountsSearchAdapter extends ArrayAdapter<Account> implements Filterable {
private List<Account> accounts;
private List<Account> accounts, tempAccounts, suggestions ;
private LayoutInflater layoutInflater;
private ImageLoader imageLoader;
private DisplayImageOptions options;
private Context context;
public AccountsSearchAdapter(Context context, List<Account> accounts){
super(context, android.R.layout.simple_list_item_1, accounts);
this.accounts = accounts;
this.tempAccounts = new ArrayList<>(accounts);
this.suggestions = new ArrayList<>(accounts);
layoutInflater = LayoutInflater.from(context);
imageLoader = ImageLoader.getInstance();
this.context = context;
@ -63,7 +70,7 @@ public class AccountsSearchAdapter extends BaseAdapter {
}
@Override
public Object getItem(int position) {
public Account getItem(int position) {
return accounts.get(position);
}
@ -73,8 +80,9 @@ public class AccountsSearchAdapter extends BaseAdapter {
}
@NonNull
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
public View getView(final int position, View convertView, @NonNull ViewGroup parent) {
final Account account = accounts.get(position);
final ViewHolder holder;
@ -106,6 +114,55 @@ public class AccountsSearchAdapter extends BaseAdapter {
return convertView;
}
@NonNull
@Override
public Filter getFilter() {
return accountFilter;
}
private Filter accountFilter = new Filter() {
@Override
public CharSequence convertResultToString(Object resultValue) {
Account account = (Account) resultValue;
return account.getDisplay_name() + " " + account.getUsername();
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
if (constraint != null) {
suggestions.clear();
for (Account account : tempAccounts) {
if (account.getAcct().toLowerCase().startsWith(constraint.toString().toLowerCase())) {
suggestions.add(account);
}
}
FilterResults filterResults = new FilterResults();
filterResults.values = suggestions;
filterResults.count = suggestions.size();
return filterResults;
} else {
return new FilterResults();
}
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
ArrayList<Account> c = (ArrayList<Account>) results.values;
if (results.count > 0) {
clear();
for (Account cust : c) {
add(cust);
notifyDataSetChanged();
}
}
else{
clear();
notifyDataSetChanged();
}
}
};
private class ViewHolder {
ImageView account_pp;

View File

@ -76,7 +76,7 @@
android:layout_margin="5dp"
app:srcCompat="@drawable/ic_close" />
</RelativeLayout>
<EditText
<AutoCompleteTextView
android:layout_marginTop="10dp"
android:id="@+id/toot_content"
android:gravity="top|start"
@ -86,103 +86,87 @@
android:minLines="4"
android:layout_weight="1"
android:layout_height="0dp" />
<RelativeLayout
android:visibility="gone"
android:id="@+id/toot_show_accounts"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ListView
android:id="@+id/toot_lv_accounts"
android:dividerHeight="0dp"
android:divider="@null"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<android.support.design.widget.FloatingActionButton
android:id="@+id/toot_close_accounts"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_gravity="center"
app:fabSize="mini"
android:layout_margin="@dimen/fab_margin"
app:srcCompat="@drawable/ic_close" />
</RelativeLayout>
<HorizontalScrollView
<LinearLayout
android:id="@+id/bottom_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<LinearLayout
android:padding="5dp"
android:id="@+id/toot_picture_container"
android:layout_width="wrap_content"
android:orientation="vertical">
<HorizontalScrollView
android:id="@+id/picture_scrollview"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxHeight="100dp"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:orientation="horizontal"
>
<ProgressBar
android:id="@+id/loading_picture"
android:visibility="gone"
android:layout_width="50dp"
android:layout_height="50dp"
android:indeterminate="true" />
<LinearLayout
android:padding="5dp"
android:id="@+id/toot_picture_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxHeight="100dp"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:orientation="horizontal"
>
<ProgressBar
android:id="@+id/loading_picture"
android:visibility="gone"
android:layout_width="50dp"
android:layout_height="50dp"
android:indeterminate="true" />
</LinearLayout>
</HorizontalScrollView>
<LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="wrap_content">
<ImageButton
android:id="@+id/toot_picture"
android:padding="5dp"
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@drawable/ic_action_camera"
tools:ignore="ContentDescription" />
<ImageButton
android:layout_marginLeft="5dp"
android:layout_marginStart="5dp"
android:id="@+id/toot_visibility"
android:padding="5dp"
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@drawable/ic_action_globe"
tools:ignore="ContentDescription" />
<Button
android:id="@+id/toot_cw"
android:padding="5dp"
android:text="@string/cw"
style="@style/Base.Widget.AppCompat.Button.Borderless.Colored"
android:layout_width="40dp"
android:layout_height="40dp" />
<TextView
android:id="@+id/toot_space_left"
android:layout_width="0dp"
android:textColor="?attr/colorAccent"
android:layout_weight="1"
android:gravity="center"
android:layout_gravity="center"
android:layout_height="40dp" />
<Button
android:id="@+id/toot_it"
android:padding="5dp"
android:text="@string/toot_it"
android:layout_gravity="end"
android:gravity="center"
style="@style/Base.Widget.AppCompat.Button.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</HorizontalScrollView>
<LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="wrap_content">
<ImageButton
android:id="@+id/toot_picture"
android:padding="5dp"
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@drawable/ic_action_camera"
tools:ignore="ContentDescription" />
<ImageButton
android:layout_marginLeft="5dp"
android:layout_marginStart="5dp"
android:id="@+id/toot_visibility"
android:padding="5dp"
android:layout_width="40dp"
android:layout_height="40dp"
android:src="@drawable/ic_action_globe"
tools:ignore="ContentDescription" />
<Button
android:id="@+id/toot_cw"
android:padding="5dp"
android:text="@string/cw"
style="@style/Base.Widget.AppCompat.Button.Borderless.Colored"
android:layout_width="40dp"
android:layout_height="40dp" />
<TextView
android:id="@+id/toot_space_left"
android:layout_width="0dp"
android:textColor="?attr/colorAccent"
android:layout_weight="1"
android:gravity="center"
android:layout_gravity="center"
android:layout_height="40dp" />
<Button
android:id="@+id/toot_it"
android:padding="5dp"
android:text="@string/toot_it"
android:layout_gravity="end"
android:gravity="center"
style="@style/Base.Widget.AppCompat.Button.Colored"
android:layout_width="wrap_content"
<CheckBox
android:text="@string/toot_sensitive"
android:visibility="gone"
android:id="@+id/toot_sensitive"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<CheckBox
android:text="@string/toot_sensitive"
android:visibility="gone"
android:id="@+id/toot_sensitive"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</ScrollView>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:visibility="gone"
android:id="@+id/toot_show_accounts"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ListView
android:id="@+id/toot_lv_accounts"
android:dividerHeight="0dp"
android:divider="@null"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<android.support.design.widget.FloatingActionButton
android:id="@+id/toot_close_accounts"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_gravity="center"
app:fabSize="mini"
android:layout_margin="@dimen/fab_margin"
app:srcCompat="@drawable/ic_close" />
</RelativeLayout>