From da2602c298cbce40b5b94a09c722f266d77cc2f2 Mon Sep 17 00:00:00 2001 From: stom79 Date: Wed, 23 Jan 2019 19:23:26 +0100 Subject: [PATCH] Add contact issue #668 --- .../mastodon/activities/BaseMainActivity.java | 42 ++++--- .../mastodon/activities/TootActivity.java | 105 +++++++++++++++++- .../RetrieveSearchAccountsAsyncTask.java | 18 ++- .../etalab/mastodon/client/PeertubeAPI.java | 9 +- .../drawers/AccountsReplyAdapter.java | 12 ++ .../fragments/DisplayListsFragment.java | 3 +- .../gouv/etalab/mastodon/helper/Helper.java | 8 +- .../OnRetrieveSearcAccountshInterface.java | 1 + .../main/res/drawable-anydpi/ic_contacts.xml | 9 ++ app/src/main/res/layout/popup_contact.xml | 33 ++++++ app/src/main/res/menu/main_toot.xml | 5 + app/src/main/res/values/strings.xml | 1 + 12 files changed, 209 insertions(+), 37 deletions(-) create mode 100644 app/src/main/res/drawable-anydpi/ic_contacts.xml create mode 100644 app/src/main/res/layout/popup_contact.xml diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/BaseMainActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/BaseMainActivity.java index 9f9287665..a83250e48 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/BaseMainActivity.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/BaseMainActivity.java @@ -2515,30 +2515,28 @@ public abstract class BaseMainActivity extends BaseActivity itemMediaOnly.setChecked(mediaOnly[0]); itemShowNSFW.setChecked(showNSFW[0]); List finalTagTimelines = tagTimelines; - popup.setOnDismissListener(new PopupMenu.OnDismissListener() { - @Override - public void onDismiss(PopupMenu menu) { - if(changes[0]) { - FragmentTransaction fragTransaction = getSupportFragmentManager().beginTransaction(); - String tag; - if (finalTagTimelines == null || finalTagTimelines.size() == 0) - tag = tabLayout.getTabAt(position).getText().toString(); - else + if (finalTagTimelines != null && finalTagTimelines.size() > 0) + popup.setOnDismissListener(new PopupMenu.OnDismissListener() { + @Override + public void onDismiss(PopupMenu menu) { + if(changes[0]) { + FragmentTransaction fragTransaction = getSupportFragmentManager().beginTransaction(); + String tag; tag = finalTagTimelines.get(0).getName(); - fragTransaction.detach(tagFragment.get(tag)); - Bundle bundle = new Bundle(); - if( mediaOnly[0]) - bundle.putString("instanceType","ART"); - else - bundle.putString("instanceType","MASTODON"); - bundle.putString("tag", tag); - bundle.putSerializable("type", RetrieveFeedsAsyncTask.Type.TAG); - tagFragment.get(tag).setArguments(bundle); - fragTransaction.attach(tagFragment.get(tag)); - fragTransaction.commit(); + fragTransaction.detach(tagFragment.get(tag)); + Bundle bundle = new Bundle(); + if( mediaOnly[0]) + bundle.putString("instanceType","ART"); + else + bundle.putString("instanceType","MASTODON"); + bundle.putString("tag", tag); + bundle.putSerializable("type", RetrieveFeedsAsyncTask.Type.TAG); + tagFragment.get(tag).setArguments(bundle); + fragTransaction.attach(tagFragment.get(tag)); + fragTransaction.commit(); + } } - } - }); + }); popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { public boolean onMenuItemClick(MenuItem item) { diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java index 730a8093a..337c177ec 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java @@ -47,9 +47,11 @@ import android.text.Html; import android.text.InputFilter; import android.text.InputType; import android.text.TextWatcher; +import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; @@ -66,6 +68,7 @@ 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; @@ -204,6 +207,11 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface, private int style; private StoredStatus scheduledstatus; private boolean isScheduled; + private List checkedValues; + private List contacts; + private ListView lv_accounts_search; + private AccountsReplyAdapter contactAdapter; + private RelativeLayout loader; @Override protected void onCreate(Bundle savedInstanceState) { @@ -265,7 +273,8 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface, currentToId = -1; restoredScheduled = false; - + checkedValues = new ArrayList<>(); + contacts = new ArrayList<>(); toot_it = findViewById(R.id.toot_it); Button toot_cw = findViewById(R.id.toot_cw); toot_space_left = findViewById(R.id.toot_space_left); @@ -787,6 +796,8 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface, } } + + private class asyncPicture extends AsyncTask { ByteArrayInputStream bs; @@ -871,6 +882,17 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface, @Override public boolean onOptionsItemSelected(MenuItem item) { final SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); + int style; + SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); + int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK); + if (theme == Helper.THEME_DARK) { + style = R.style.DialogDark; + } else if (theme == Helper.THEME_BLACK){ + style = R.style.DialogBlack; + }else { + style = R.style.Dialog; + } + switch (item.getItemId()) { case android.R.id.home: finish(); @@ -905,8 +927,6 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface, return true; case R.id.action_translate: final CountryPicker picker = CountryPicker.newInstance(getString(R.string.which_language)); // dialog title - final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, android.content.Context.MODE_PRIVATE); - final int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK); if( theme == Helper.THEME_LIGHT){ picker.setStyle(R.style.AppTheme, R.style.AlertDialog); }else { @@ -1098,6 +1118,62 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface, return true; case R.id.action_photo_camera: dispatchTakePictureIntent(); + return true; + case R.id.action_contacts: + + AlertDialog.Builder builderSingle = new AlertDialog.Builder(TootActivity.this, style); + + builderSingle.setTitle(getString(R.string.select_accounts)); + LayoutInflater inflater = getLayoutInflater(); + @SuppressLint("InflateParams") View dialogView = inflater.inflate(R.layout.popup_contact, null); + + loader = dialogView.findViewById(R.id.loader); + EditText search_account = dialogView.findViewById(R.id.search_account); + lv_accounts_search = dialogView.findViewById(R.id.lv_accounts_search); + loader.setVisibility(View.VISIBLE); + new RetrieveSearchAccountsAsyncTask(TootActivity.this, "a", true,TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + + search_account.addTextChangedListener(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) { + if (count > 0) { + search_account.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_close, 0); + }else{ + search_account.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_search, 0); + } + } + @Override + public void afterTextChanged(Editable s) { + if( s != null && s.length() > 0){ + new RetrieveSearchAccountsAsyncTask(TootActivity.this, s.toString(), true,TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + } + }); + search_account.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + final int DRAWABLE_RIGHT = 2; + if (event.getAction() == MotionEvent.ACTION_UP) { + if (search_account.length() > 0 && event.getRawX() >= (search_account.getRight() - search_account.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) { + search_account.setText(""); + } + } + + return false; + } + }); + builderSingle.setView(dialogView); + builderSingle.setNegativeButton(R.string.validate, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + toot_content.setSelection(toot_content.getText().length()); + } + }); + builderSingle.show(); + return true; case R.id.action_microphone: Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); @@ -1129,7 +1205,7 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface, Toasty.info(getApplicationContext(), getString(R.string.no_draft), Toast.LENGTH_LONG).show(); return true; } - AlertDialog.Builder builderSingle = new AlertDialog.Builder(TootActivity.this, style); + builderSingle = new AlertDialog.Builder(TootActivity.this, style); builderSingle.setTitle(getString(R.string.choose_toot)); final DraftsListAdapter draftsListAdapter = new DraftsListAdapter(TootActivity.this, drafts); final int[] ids = new int[drafts.size()]; @@ -1188,8 +1264,8 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface, return true; } AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(TootActivity.this, style); - LayoutInflater inflater = this.getLayoutInflater(); - @SuppressLint("InflateParams") View dialogView = inflater.inflate(R.layout.datetime_picker, null); + inflater = this.getLayoutInflater(); + dialogView = inflater.inflate(R.layout.datetime_picker, null); dialogBuilder.setView(dialogView); final AlertDialog alertDialog = dialogBuilder.create(); @@ -1844,6 +1920,23 @@ public class TootActivity extends BaseActivity implements OnPostActionInterface, } } + @Override + public void onRetrieveContact(APIResponse apiResponse) { + if( apiResponse.getError() != null || apiResponse.getAccounts() == null || apiResponse.getAccounts().size() == 0) + return; + if( contacts == null) { + this.contacts = new ArrayList<>(); + } + this.contacts = apiResponse.getAccounts(); + for(Account account: contacts) { + checkedValues.add(toot_content.getText().toString().contains("@" + account.getAcct())); + Log.v(Helper.TAG,"@" + account.getAcct() + " -> " + toot_content.getText().toString().contains("@" + account.getAcct())); + } + loader.setVisibility(View.GONE); + contactAdapter = new AccountsReplyAdapter(TootActivity.this, contacts, checkedValues); + lv_accounts_search.setAdapter(contactAdapter); + } + @Override public void onRetrieveEmoji(Status status, boolean fromTranslation) { diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveSearchAccountsAsyncTask.java b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveSearchAccountsAsyncTask.java index 1c2d81c03..9ccad6293 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveSearchAccountsAsyncTask.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveSearchAccountsAsyncTask.java @@ -35,24 +35,38 @@ public class RetrieveSearchAccountsAsyncTask extends AsyncTask private APIResponse apiResponse; private OnRetrieveSearcAccountshInterface listener; private WeakReference contextReference; + private boolean following; public RetrieveSearchAccountsAsyncTask(Context context, String query, OnRetrieveSearcAccountshInterface onRetrieveSearcAccountshInterface){ this.contextReference = new WeakReference<>(context); this.query = query; this.listener = onRetrieveSearcAccountshInterface; + this.following = false; } + public RetrieveSearchAccountsAsyncTask(Context context, String query, boolean following, OnRetrieveSearcAccountshInterface onRetrieveSearcAccountshInterface){ + this.contextReference = new WeakReference<>(context); + this.query = query; + this.listener = onRetrieveSearcAccountshInterface; + this.following = following; + } @Override protected Void doInBackground(Void... params) { API api = new API(this.contextReference.get()); - apiResponse = api.searchAccounts(query, 20); + if( !following) + apiResponse = api.searchAccounts(query, 20); + else + apiResponse = new API(contextReference.get()).searchAccounts(query, 20, true); return null; } @Override protected void onPostExecute(Void result) { - listener.onRetrieveSearchAccounts(apiResponse); + if( !following) + listener.onRetrieveSearchAccounts(apiResponse); + else + listener.onRetrieveContact(apiResponse); } } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/client/PeertubeAPI.java b/app/src/main/java/fr/gouv/etalab/mastodon/client/PeertubeAPI.java index 9e3e9b44a..aad745c91 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/client/PeertubeAPI.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/client/PeertubeAPI.java @@ -92,8 +92,13 @@ public class PeertubeAPI { this.instance = Helper.getLiveInstance(context); else { SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); - String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null); - Account account = new AccountDAO(context, db).getAccountByID(userId); + String token = sharedpreferences.getString(Helper.PREF_KEY_OAUTH_TOKEN, null); + Account account = new AccountDAO(context, db).getAccountByToken(token); + if( account == null) { + apiResponse = new APIResponse(); + APIError = new Error(); + return; + } this.instance = account.getInstance().trim(); } this.prefKeyOauthTokenT = sharedpreferences.getString(Helper.PREF_KEY_OAUTH_TOKEN, null); diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/AccountsReplyAdapter.java b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/AccountsReplyAdapter.java index ebab8950a..14a33d403 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/AccountsReplyAdapter.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/AccountsReplyAdapter.java @@ -55,6 +55,18 @@ public class AccountsReplyAdapter extends BaseAdapter{ this.checked = checked; } + public AccountsReplyAdapter(Context context, List accounts, List checked){ + this.accounts = accounts; + this.context = context; + layoutInflater = LayoutInflater.from(context); + this.checked = new boolean[checked.size()]; + int index = 0; + for (Boolean val : checked) { + this.checked[index++] = val; + } + + } + @Override public int getCount() { return accounts.size(); diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayListsFragment.java b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayListsFragment.java index c427d3eb4..23a524ef0 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayListsFragment.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayListsFragment.java @@ -15,6 +15,7 @@ package fr.gouv.etalab.mastodon.fragments; * see . */ import android.annotation.SuppressLint; +import android.app.Activity; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; @@ -103,7 +104,7 @@ public class DisplayListsFragment extends Fragment implements OnListActionInterf style = R.style.Dialog; } AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context, style); - LayoutInflater inflater = getLayoutInflater(); + LayoutInflater inflater = ((Activity)context).getLayoutInflater(); @SuppressLint("InflateParams") View dialogView = inflater.inflate(R.layout.add_list, null); dialogBuilder.setView(dialogView); final EditText editText = dialogView.findViewById(R.id.add_list); diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java b/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java index c866296fe..0b849c91e 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java @@ -1682,11 +1682,11 @@ public class Helper { } } - FloatingActionMenu actionMenuAcc = actionMenuAccBuilder.attachTo(actionButtonAcc) - .setStartAngle(0) - .setEndAngle(135) - .build(); if( actionButtonAcc != null) { + FloatingActionMenu actionMenuAcc = actionMenuAccBuilder.attachTo(actionButtonAcc) + .setStartAngle(0) + .setEndAngle(135) + .build(); if( accounts.size() > 2){ actionButtonAcc.setFocusableInTouchMode(true); actionButtonAcc.setFocusable(true); diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRetrieveSearcAccountshInterface.java b/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRetrieveSearcAccountshInterface.java index b46c8b92e..07247f520 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRetrieveSearcAccountshInterface.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRetrieveSearcAccountshInterface.java @@ -23,4 +23,5 @@ import fr.gouv.etalab.mastodon.client.APIResponse; */ public interface OnRetrieveSearcAccountshInterface { void onRetrieveSearchAccounts(APIResponse apiResponse); + void onRetrieveContact(APIResponse apiResponse); } diff --git a/app/src/main/res/drawable-anydpi/ic_contacts.xml b/app/src/main/res/drawable-anydpi/ic_contacts.xml new file mode 100644 index 000000000..fbcf8c2bf --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_contacts.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/popup_contact.xml b/app/src/main/res/layout/popup_contact.xml new file mode 100644 index 000000000..487bd9cde --- /dev/null +++ b/app/src/main/res/layout/popup_contact.xml @@ -0,0 +1,33 @@ + + + + + + + + diff --git a/app/src/main/res/menu/main_toot.xml b/app/src/main/res/menu/main_toot.xml index 4b889bcd8..b0e6a2042 100644 --- a/app/src/main/res/menu/main_toot.xml +++ b/app/src/main/res/menu/main_toot.xml @@ -16,6 +16,11 @@ android:title="@string/camera" android:icon="@drawable/ic_photo_camera" app:showAsAction="ifRoom" /> + Interface Hidden content Composing + Contacts