diff --git a/app/src/main/java/app/fedilab/android/activities/TootActivity.java b/app/src/main/java/app/fedilab/android/activities/TootActivity.java index 422f7ab69..f2caf22ce 100644 --- a/app/src/main/java/app/fedilab/android/activities/TootActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/TootActivity.java @@ -53,6 +53,7 @@ import android.text.Html; import android.text.InputFilter; import android.text.InputType; import android.text.TextWatcher; +import android.util.Log; import android.util.Patterns; import android.view.LayoutInflater; import android.view.Menu; @@ -193,6 +194,7 @@ import static app.fedilab.android.helper.Helper.orbotConnected; public class TootActivity extends BaseActivity implements UploadStatusDelegate, OnPostActionInterface, OnRetrieveSearcAccountshInterface, OnPostStatusActionInterface, OnRetrieveSearchInterface, OnRetrieveAccountsReplyInterface, OnRetrieveEmojiInterface, OnDownloadInterface, OnRetrieveAttachmentInterface { + private String visibility; private final int PICK_IMAGE = 56556; private final int TAKE_PHOTO = 56532; @@ -218,7 +220,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate, private Toast mToast; private RelativeLayout drawer_layout; private HorizontalScrollView picture_scrollview; - private int currentCursorPosition, searchLength; + private int searchLength; private TextView toot_space_left; private String initialContent; public static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 754; @@ -521,11 +523,11 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate, if (mentionAccount != null) { toot_content.setText(String.format("@%s\n", mentionAccount)); toot_content.setSelection(toot_content.getText().length()); - toot_space_left.setText(String.valueOf(countLength())); + toot_space_left.setText(String.valueOf(countLength(toot_content, toot_cw_content))); } if (tootMention != null && urlMention != null) { toot_content.setText(String.format("\n\nvia @%s\n\n%s\n\n", tootMention, urlMention)); - toot_space_left.setText(String.valueOf(countLength())); + toot_space_left.setText(String.valueOf(countLength(toot_content, toot_cw_content))); } @@ -559,7 +561,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate, toot_content.setText(sharedContent); if (selectionBefore >= 0 && selectionBefore < toot_content.length()) toot_content.setSelection(selectionBefore); - toot_space_left.setText(String.valueOf(countLength())); + toot_space_left.setText(String.valueOf(countLength(toot_content, toot_cw_content))); } if (image != null) { new HttpsConnection(TootActivity.this, instance).download(image, TootActivity.this); @@ -568,7 +570,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate, toot_content.setText(String.format("\n%s", sharedContent)); if (selectionBefore >= 0 && selectionBefore < toot_content.length()) toot_content.setSelection(selectionBefore); - toot_space_left.setText(String.valueOf(countLength())); + toot_space_left.setText(String.valueOf(countLength(toot_content, toot_cw_content))); } } @@ -607,7 +609,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate, } }); - toot_space_left.setText(String.valueOf(countLength())); + toot_space_left.setText(String.valueOf(countLength(toot_content, toot_cw_content))); toot_cw.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -704,14 +706,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate, } }); - String pattern = "^(.|\\s)*(@([a-zA-Z0-9_]{2,}))$"; - final Pattern sPattern = Pattern.compile(pattern); - String patternTag = "^(.|\\s)*(#([\\w-]{2,}))$"; - final Pattern tPattern = Pattern.compile(patternTag); - - String patternEmoji = "^(.|\\s)*(:([\\w_]+))$"; - final Pattern ePattern = Pattern.compile(patternEmoji); toot_cw_content.addTextChangedListener(new TextWatcher() { @Override @@ -724,127 +719,11 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate, @Override public void afterTextChanged(Editable s) { - toot_space_left.setText(String.valueOf(countLength())); + toot_space_left.setText(String.valueOf(countLength(toot_content, toot_cw_content))); } }); - 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) { - - } - - @Override - public void afterTextChanged(Editable s) { - if (autocomplete) { - toot_content.removeTextChangedListener(textWatcher); - Thread thread = new Thread() { - @Override - public void run() { - String fedilabHugsTrigger = ":fedilab_hugs:"; - - int currentLength = countLength(); - int toFill = 500 + fedilabHugsTrigger.length() - currentLength; - if(toFill <= 0) { - return; - } - - newContent = s.toString().replaceAll(fedilabHugsTrigger, ""); - - StringBuilder hugs = new StringBuilder(); - for(int i = 0; i < toFill; i++) { - hugs.append(new String(Character.toChars(0x1F917))); - } - - newContent = newContent + hugs.toString(); - toot_content.setText(newContent); - toot_content.setSelection(toot_content.getText().length()); - toot_content.addTextChangedListener(textWatcher); - autocomplete = false; - toot_space_left.setText(String.valueOf(countLength())); - } - }; - thread.start(); - return; - } - - if (toot_content.getSelectionStart() != 0) - currentCursorPosition = toot_content.getSelectionStart(); - if (s.toString().length() == 0) - currentCursorPosition = 0; - //Only check last 15 characters before cursor position to avoid lags - if (currentCursorPosition < 15) { //Less than 15 characters are written before the cursor position - searchLength = currentCursorPosition; - } else { - searchLength = 15; - } - - - int totalChar = countLength(); - toot_space_left.setText(String.valueOf(totalChar)); - if (currentCursorPosition - (searchLength - 1) < 0 || currentCursorPosition == 0 || currentCursorPosition > s.toString().length()) - return; - - String patternh = "^(.|\\s)*(:fedilab_hugs:)$"; - final Pattern hPattern = Pattern.compile(patternh); - Matcher mh = hPattern.matcher((s.toString().substring(currentCursorPosition - searchLength, currentCursorPosition))); - - if (mh.matches()) { - autocomplete = true; - return; - } - - Matcher m, mt; - if (s.toString().charAt(0) == '@') - m = sPattern.matcher(s.toString().substring(currentCursorPosition - searchLength, currentCursorPosition)); - else - m = sPattern.matcher(s.toString().substring(currentCursorPosition - (searchLength - 1), currentCursorPosition)); - if (m.matches()) { - String search = m.group(3); - if (pp_progress != null && pp_actionBar != null) { - pp_progress.setVisibility(View.VISIBLE); - pp_actionBar.setVisibility(View.GONE); - } - new RetrieveSearchAccountsAsyncTask(getApplicationContext(), search, TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } else { - if (s.toString().charAt(0) == '#') - mt = tPattern.matcher(s.toString().substring(currentCursorPosition - searchLength, currentCursorPosition)); - else - mt = tPattern.matcher(s.toString().substring(currentCursorPosition - (searchLength - 1), currentCursorPosition)); - if (mt.matches()) { - String search = mt.group(3); - if (pp_progress != null && pp_actionBar != null) { - pp_progress.setVisibility(View.VISIBLE); - pp_actionBar.setVisibility(View.GONE); - } - new RetrieveSearchAsyncTask(getApplicationContext(), search, true, TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } else { - if (s.toString().charAt(0) == ':') - mt = ePattern.matcher(s.toString().substring(currentCursorPosition - searchLength, currentCursorPosition)); - else - mt = ePattern.matcher(s.toString().substring(currentCursorPosition - (searchLength - 1), currentCursorPosition)); - if (mt.matches()) { - String shortcode = mt.group(3); - if (pp_progress != null && pp_actionBar != null) { - pp_progress.setVisibility(View.VISIBLE); - pp_actionBar.setVisibility(View.GONE); - } - new RetrieveEmojiAsyncTask(getApplicationContext(), shortcode, TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } else { - toot_content.dismissDropDown(); - } - } - } - - - totalChar = countLength(); - toot_space_left.setText(String.valueOf(totalChar)); - } - }; + textWatcher = initializeTextWatcher(getApplicationContext(), toot_content, toot_cw_content, toot_space_left, pp_actionBar, pp_progress, TootActivity.this, TootActivity.this, TootActivity.this); if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON || MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA) toot_content.addTextChangedListener(textWatcher); @@ -863,7 +742,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate, } }); - toot_space_left.setText(String.valueOf(countLength())); + toot_space_left.setText(String.valueOf(countLength(toot_content, toot_cw_content))); LocalBroadcastManager.getInstance(this) .registerReceiver(imageReceiver, @@ -873,6 +752,145 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate, uploadReceiver.register(this); } + public static TextWatcher initializeTextWatcher(Context context, + MastalabAutoCompleteTextView toot_content, EditText toot_cw_content, TextView toot_space_left, + ImageView pp_actionBar, ProgressBar pp_progress, + OnRetrieveSearchInterface listener, OnRetrieveSearcAccountshInterface listenerAccount, OnRetrieveEmojiInterface listenerEmoji + ){ + + String pattern = "^(.|\\s)*(@([a-zA-Z0-9_]{2,}))$"; + final Pattern sPattern = Pattern.compile(pattern); + + String patternTag = "^(.|\\s)*(#([\\w-]{2,}))$"; + final Pattern tPattern = Pattern.compile(patternTag); + + String patternEmoji = "^(.|\\s)*(:([\\w_]+))$"; + final Pattern ePattern = Pattern.compile(patternEmoji); + final int[] currentCursorPosition = {toot_content.getSelectionStart()}; + final String[] newContent = {null}; + final int[] searchLength = {15}; + TextWatcher textw = null; + TextWatcher finalTextw = textw; + textw = 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) { + + } + + @Override + public void afterTextChanged(Editable s) { + if (autocomplete) { + toot_content.removeTextChangedListener(finalTextw); + Thread thread = new Thread() { + @Override + public void run() { + String fedilabHugsTrigger = ":fedilab_hugs:"; + + int currentLength = countLength(toot_content, toot_cw_content); + int toFill = 500 + fedilabHugsTrigger.length() - currentLength; + if(toFill <= 0) { + return; + } + + newContent[0] = s.toString().replaceAll(fedilabHugsTrigger, ""); + + StringBuilder hugs = new StringBuilder(); + for(int i = 0; i < toFill; i++) { + hugs.append(new String(Character.toChars(0x1F917))); + } + + newContent[0] = newContent[0] + hugs.toString(); + toot_content.setText(newContent[0]); + toot_content.setSelection(toot_content.getText().length()); + toot_content.addTextChangedListener(finalTextw); + autocomplete = false; + toot_space_left.setText(String.valueOf(countLength(toot_content, toot_cw_content))); + } + }; + thread.start(); + return; + } + + if (toot_content.getSelectionStart() != 0) + currentCursorPosition[0] = toot_content.getSelectionStart(); + if (s.toString().length() == 0) + currentCursorPosition[0] = 0; + //Only check last 15 characters before cursor position to avoid lags + if (currentCursorPosition[0] < 15) { //Less than 15 characters are written before the cursor position + searchLength[0] = currentCursorPosition[0]; + } else { + searchLength[0] = 15; + } + + + int totalChar = countLength(toot_content, toot_cw_content); + toot_space_left.setText(String.valueOf(totalChar)); + if (currentCursorPosition[0] - (searchLength[0] - 1) < 0 || currentCursorPosition[0] == 0 || currentCursorPosition[0] > s.toString().length()) + return; + + String patternh = "^(.|\\s)*(:fedilab_hugs:)$"; + final Pattern hPattern = Pattern.compile(patternh); + Matcher mh = hPattern.matcher((s.toString().substring(currentCursorPosition[0] - searchLength[0], currentCursorPosition[0]))); + + if (mh.matches()) { + autocomplete = true; + return; + } + + Matcher m, mt; + if (s.toString().charAt(0) == '@') + m = sPattern.matcher(s.toString().substring(currentCursorPosition[0] - searchLength[0], currentCursorPosition[0])); + else + m = sPattern.matcher(s.toString().substring(currentCursorPosition[0] - (searchLength[0] - 1), currentCursorPosition[0])); + if (m.matches()) { + String search = m.group(3); + if (pp_progress != null && pp_actionBar != null) { + pp_progress.setVisibility(View.VISIBLE); + pp_actionBar.setVisibility(View.GONE); + } + new RetrieveSearchAccountsAsyncTask(context, search, listenerAccount).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } else { + if (s.toString().charAt(0) == '#') + mt = tPattern.matcher(s.toString().substring(currentCursorPosition[0] - searchLength[0], currentCursorPosition[0])); + else + mt = tPattern.matcher(s.toString().substring(currentCursorPosition[0] - (searchLength[0] - 1), currentCursorPosition[0])); + if (mt.matches()) { + String search = mt.group(3); + if (pp_progress != null && pp_actionBar != null) { + pp_progress.setVisibility(View.VISIBLE); + pp_actionBar.setVisibility(View.GONE); + } + new RetrieveSearchAsyncTask(context, search, true, listener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } else { + if (s.toString().charAt(0) == ':') + mt = ePattern.matcher(s.toString().substring(currentCursorPosition[0] - searchLength[0], currentCursorPosition[0])); + else + mt = ePattern.matcher(s.toString().substring(currentCursorPosition[0] - (searchLength[0] - 1), currentCursorPosition[0])); + if (mt.matches()) { + String shortcode = mt.group(3); + if (pp_progress != null && pp_actionBar != null) { + pp_progress.setVisibility(View.VISIBLE); + pp_actionBar.setVisibility(View.GONE); + } + new RetrieveEmojiAsyncTask(context, shortcode, listenerEmoji).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } else { + toot_content.dismissDropDown(); + } + } + } + + + totalChar = countLength(toot_content, toot_cw_content); + toot_space_left.setText(String.valueOf(totalChar)); + } + }; + return textw; + } + private BroadcastReceiver imageReceiver = new BroadcastReceiver() { @Override @@ -1142,7 +1160,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate, //Adds the shorter text_url of attachment at the end of the toot
 int selectionBefore = toot_content.getSelectionStart(); toot_content.setText(String.format("%s\n\n%s",toot_content.getText().toString(), attachment.getText_url())); - toot_space_left.setText(String.valueOf(countLength())); + toot_space_left.setText(String.valueOf(countLength(toot_content, toot_cw_content))); //Moves the cursor toot_content.setSelection(selectionBefore); } @@ -1788,7 +1806,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate, String tootContent; if( toot_cw_content.getText() != null && toot_cw_content.getText().toString().trim().length() > 0 ) split_toot_size -= toot_cw_content.getText().toString().trim().length(); - if( MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA || !split_toot || (countLength() < split_toot_size)){ + if( MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA || !split_toot || (countLength(toot_content, toot_cw_content) < split_toot_size)){ tootContent = toot_content.getText().toString().trim(); }else{ splitToot = Helper.splitToots(toot_content.getText().toString().trim(), split_toot_size); @@ -2039,7 +2057,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate, //Clears the text_url at the end of the toot
 for this attachment int selectionBefore = toot_content.getSelectionStart(); toot_content.setText(toot_content.getText().toString().replace(attachment.getText_url(), "")); - toot_space_left.setText(String.valueOf(countLength())); + toot_space_left.setText(String.valueOf(countLength(toot_content, toot_cw_content))); //Moves the cursor if (selectionBefore >= 0 && selectionBefore < toot_content.length()) toot_content.setSelection(selectionBefore); @@ -2284,6 +2302,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate, return; final List accounts = apiResponse.getAccounts(); if( accounts != null && accounts.size() > 0){ + int currentCursorPosition = toot_content.getSelectionStart(); AccountsSearchAdapter accountsListAdapter = new AccountsSearchAdapter(TootActivity.this, accounts); toot_content.setThreshold(1); toot_content.setAdapter(accountsListAdapter); @@ -2313,7 +2332,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate, if (currentCursorPosition < oldContent.length() ) newContent += oldContent.substring(currentCursorPosition, oldContent.length()); toot_content.setText(newContent); - toot_space_left.setText(String.valueOf(countLength())); + toot_space_left.setText(String.valueOf(countLength(toot_content, toot_cw_content))); toot_content.setSelection(newPosition); AccountsSearchAdapter accountsListAdapter = new AccountsSearchAdapter(TootActivity.this, new ArrayList<>()); toot_content.setThreshold(1); @@ -2356,6 +2375,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate, pp_progress.setVisibility(View.GONE); pp_actionBar.setVisibility(View.VISIBLE); } + int currentCursorPosition = toot_content.getSelectionStart(); if( emojis != null && emojis.size() > 0){ EmojisSearchAdapter emojisSearchAdapter = new EmojisSearchAdapter(TootActivity.this, emojis); toot_content.setThreshold(1); @@ -2384,7 +2404,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate, if( currentCursorPosition < oldContent.length() ) newContent += oldContent.substring(currentCursorPosition, oldContent.length()-1); toot_content.setText(newContent); - toot_space_left.setText(String.valueOf(countLength())); + toot_space_left.setText(String.valueOf(countLength(toot_content, toot_cw_content))); toot_content.setSelection(newPosition); EmojisSearchAdapter emojisSearchAdapter = new EmojisSearchAdapter(TootActivity.this, new ArrayList<>()); toot_content.setThreshold(1); @@ -2463,6 +2483,8 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate, @Override public void onRetrieveSearch(APIResponse apiResponse) { + + int currentCursorPosition = toot_content.getSelectionStart(); if( pp_progress != null && pp_actionBar != null) { pp_progress.setVisibility(View.GONE); pp_actionBar.setVisibility(View.VISIBLE); @@ -2505,7 +2527,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate, if( currentCursorPosition < oldContent.length() ) newContent += oldContent.substring(currentCursorPosition, oldContent.length()-1); toot_content.setText(newContent); - toot_space_left.setText(String.valueOf(countLength())); + toot_space_left.setText(String.valueOf(countLength(toot_content, toot_cw_content))); toot_content.setSelection(newPosition); TagsSearchAdapter tagsSearchAdapter = new TagsSearchAdapter(TootActivity.this, new ArrayList<>()); toot_content.setThreshold(1); @@ -2635,7 +2657,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate, } toot_content.setText(content); - toot_space_left.setText(String.valueOf(countLength())); + toot_space_left.setText(String.valueOf(countLength(toot_content, toot_cw_content))); toot_content.setSelection(toot_content.getText().length()); switch (status.getVisibility()){ case "public": @@ -2678,7 +2700,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate, } invalidateOptionsMenu(); initialContent = toot_content.getText().toString(); - toot_space_left.setText(String.valueOf(countLength())); + toot_space_left.setText(String.valueOf(countLength(toot_content, toot_cw_content))); } @@ -2785,7 +2807,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate, } toot_content.setText(content); - toot_space_left.setText(String.valueOf(countLength())); + toot_space_left.setText(String.valueOf(countLength(toot_content, toot_cw_content))); toot_content.setSelection(toot_content.getText().length()); switch (status.getVisibility()){ case "public": @@ -2820,7 +2842,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate, } invalidateOptionsMenu(); initialContent = toot_content.getText().toString(); - toot_space_left.setText(String.valueOf(countLength())); + toot_space_left.setText(String.valueOf(countLength(toot_content, toot_cw_content))); } private void tootReply(){ @@ -2913,52 +2935,9 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate, toot_cw_content.setText(tootReply.getSpoiler_text()); toot_cw_content.setVisibility(View.VISIBLE); } - //Retrieves mentioned accounts + OP and adds them at the beginin of the toot - ArrayList mentionedAccountsAdded = new ArrayList<>(); - int cursorReply = 0; - if( tootReply.getAccount() != null && tootReply.getAccount().getAcct() != null && !tootReply.getAccount().getId().equals(userIdReply)) { - toot_content.setText(String.format("@%s", tootReply.getAccount().getAcct())); - mentionedAccountsAdded.add(tootReply.getAccount().getAcct()); - //Evaluate the cursor position => mention length + 1 char for carriage return - cursorReply = toot_content.getText().toString().length() + 1; - } - if( tootReply.getMentions() != null ){ - //Put other accounts mentioned at the bottom - boolean capitalize = sharedpreferences.getBoolean(Helper.SET_CAPITALIZE, true); - if( capitalize) - toot_content.setText(String.format("%s", (toot_content.getText().toString() + "\n\n"))); - else - toot_content.setText(String.format("%s", (toot_content.getText().toString() + " "))); - for(Mention mention : tootReply.getMentions()){ - if( mention.getAcct() != null && !mention.getId().equals(userIdReply) && !mentionedAccountsAdded.contains(mention.getAcct())) { - mentionedAccountsAdded.add(mention.getAcct()); - String tootTemp = String.format("@%s ", mention.getAcct()); - toot_content.setText(String.format("%s ", (toot_content.getText().toString() + tootTemp.trim()))); - } - } - toot_content.setText(toot_content.getText().toString().trim()); - if (toot_content.getText().toString().startsWith("@") ) { - if( capitalize ) - toot_content.append("\n"); - else - toot_content.append(" "); - } - toot_space_left.setText(String.valueOf(countLength())); - toot_content.requestFocus(); - - if( capitalize) { - if (mentionedAccountsAdded.size() == 1) { - toot_content.setSelection(toot_content.getText().length()); //Put cursor at the end - } else { - if (cursorReply > 0 && cursorReply < toot_content.getText().length()) - toot_content.setSelection(cursorReply); - else - toot_content.setSelection(toot_content.getText().length()); //Put cursor at the end - } - }else { - toot_content.setSelection(toot_content.getText().length()); //Put cursor at the end - } + if( tootReply != null) { + manageMentions(getApplicationContext(), userIdReply, toot_content, toot_cw_content, toot_space_left, tootReply); } boolean forwardTags = sharedpreferences.getBoolean(Helper.SET_FORWARD_TAGS_IN_REPLY, false); if( tootReply != null && forwardTags && tootReply.getTags() != null && tootReply.getTags().size() > 0){ @@ -2968,7 +2947,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate, toot_content.setText(toot_content.getText() +" #"+tag.getName()); } toot_content.setSelection(currentCursorPosition); - toot_space_left.setText(String.valueOf(countLength())); + toot_space_left.setText(String.valueOf(countLength(toot_content, toot_cw_content))); } } @@ -2976,6 +2955,60 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate, } + public static void manageMentions(Context context, String userIdReply, MastalabAutoCompleteTextView contentView, EditText CWView, TextView counterView, Status tootReply){ + + //Retrieves mentioned accounts + OP and adds them at the beginin of the toot + ArrayList mentionedAccountsAdded = new ArrayList<>(); + final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE); + int cursorReply = 0; + if( tootReply.getAccount() != null && tootReply.getAccount().getAcct() != null && !tootReply.getAccount().getId().equals(userIdReply)) { + contentView.setText(String.format("@%s", tootReply.getAccount().getAcct())); + mentionedAccountsAdded.add(tootReply.getAccount().getAcct()); + //Evaluate the cursor position => mention length + 1 char for carriage return + cursorReply = contentView.getText().toString().length() + 1; + } + + if( tootReply.getMentions() != null ){ + //Put other accounts mentioned at the bottom + boolean capitalize = sharedpreferences.getBoolean(Helper.SET_CAPITALIZE, true); + if( capitalize) + contentView.setText(String.format("%s", (contentView.getText().toString() + "\n\n"))); + else + contentView.setText(String.format("%s", (contentView.getText().toString() + " "))); + for(Mention mention : tootReply.getMentions()){ + Log.v(Helper.TAG, mention.getAcct()); + if( mention.getAcct() != null && !mention.getId().equals(userIdReply) && !mentionedAccountsAdded.contains(mention.getAcct())) { + mentionedAccountsAdded.add(mention.getAcct()); + String tootTemp = String.format("@%s ", mention.getAcct()); + contentView.setText(String.format("%s ", (contentView.getText().toString() + tootTemp.trim()))); + } + } + + contentView.setText(contentView.getText().toString().trim()); + if (contentView.getText().toString().startsWith("@") ) { + if( capitalize ) + contentView.append("\n"); + else + contentView.append(" "); + } + counterView.setText(String.valueOf(countLength(contentView, CWView))); + contentView.requestFocus(); + + if( capitalize) { + if (mentionedAccountsAdded.size() == 1) { + contentView.setSelection(contentView.getText().length()); //Put cursor at the end + } else { + if (cursorReply > 0 && cursorReply < contentView.getText().length()) + contentView.setSelection(cursorReply); + else + contentView.setSelection(contentView.getText().length()); //Put cursor at the end + } + }else { + contentView.setSelection(contentView.getText().length()); //Put cursor at the end + } + } + } + private void displayPollPopup(){ AlertDialog.Builder alertPoll = new AlertDialog.Builder(TootActivity.this, style); alertPoll.setTitle(R.string.create_poll); @@ -3341,7 +3374,7 @@ public class TootActivity extends BaseActivity implements UploadStatusDelegate, } - private int countLength(){ + public static int countLength(MastalabAutoCompleteTextView toot_content, EditText toot_cw_content){ if( toot_content == null || toot_cw_content == null) { return -1; } diff --git a/app/src/main/java/app/fedilab/android/drawers/StatusListAdapter.java b/app/src/main/java/app/fedilab/android/drawers/StatusListAdapter.java index 89ce85398..6745e30d4 100644 --- a/app/src/main/java/app/fedilab/android/drawers/StatusListAdapter.java +++ b/app/src/main/java/app/fedilab/android/drawers/StatusListAdapter.java @@ -46,6 +46,7 @@ import android.text.SpannableString; import android.text.Spanned; import android.text.TextPaint; import android.text.TextUtils; +import android.text.TextWatcher; import android.text.method.LinkMovementMethod; import android.text.style.ClickableSpan; import android.text.style.ForegroundColorSpan; @@ -121,6 +122,8 @@ import app.fedilab.android.helper.CrossActions; import app.fedilab.android.helper.CustomTextView; import app.fedilab.android.helper.Helper; import app.fedilab.android.helper.MastalabAutoCompleteTextView; +import app.fedilab.android.interfaces.OnRetrieveSearcAccountshInterface; +import app.fedilab.android.interfaces.OnRetrieveSearchInterface; import app.fedilab.android.jobs.ScheduledBoostsSyncJob; import app.fedilab.android.sqlite.AccountDAO; import app.fedilab.android.sqlite.CustomEmojiDAO; @@ -168,7 +171,7 @@ import static app.fedilab.android.helper.Helper.changeDrawableColor; * Created by Thomas on 24/04/2017. * Adapter for Status */ -public class StatusListAdapter extends RecyclerView.Adapter implements OnPostActionInterface, OnRetrieveFeedsInterface, OnRetrieveEmojiInterface, OnRetrieveRepliesInterface, OnRetrieveCardInterface, OnPollInterface, OnRefreshCachedStatusInterface { +public class StatusListAdapter extends RecyclerView.Adapter implements OnPostActionInterface, OnRetrieveFeedsInterface, OnRetrieveEmojiInterface, OnRetrieveRepliesInterface, OnRetrieveCardInterface, OnPollInterface, OnRefreshCachedStatusInterface, OnRetrieveSearcAccountshInterface, OnRetrieveSearchInterface { private Context context; private List statuses; @@ -189,6 +192,9 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct private TagTimeline tagTimeline; public static boolean fetch_all_more = false; private AlertDialog alertDialogEmoji; + private static MastalabAutoCompleteTextView toot_content; + private static EditText toot_cw_content; + private static TextView toot_space_left; public StatusListAdapter(Context context, RetrieveFeedsAsyncTask.Type type, String targetedId, boolean isOnWifi, List statuses){ super(); @@ -278,6 +284,155 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct statusListAdapter.notifyStatusWithActionChanged(refreshedStatus); } + @Override + public void onRetrieveSearchAccounts(APIResponse apiResponse) { + if( apiResponse.getError() != null) + return; + int searchLength = 15; + final List accounts = apiResponse.getAccounts(); + if( accounts != null && accounts.size() > 0){ + int currentCursorPosition = toot_content.getSelectionStart(); + AccountsSearchAdapter accountsListAdapter = new AccountsSearchAdapter(context, accounts); + toot_content.setThreshold(1); + toot_content.setAdapter(accountsListAdapter); + final String oldContent = toot_content.getText().toString(); + if( oldContent.length() >= currentCursorPosition) { + String[] searchA = oldContent.substring(0, currentCursorPosition).split("@"); + if (searchA.length > 0) { + final String search = searchA[searchA.length - 1]; + toot_content.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + Account account = accounts.get(position); + String deltaSearch = ""; + if (currentCursorPosition - searchLength > 0 && currentCursorPosition < oldContent.length()) + deltaSearch = oldContent.substring(currentCursorPosition - searchLength, currentCursorPosition); + else { + if (currentCursorPosition >= oldContent.length()) + deltaSearch = oldContent.substring(currentCursorPosition - searchLength, oldContent.length()); + } + + if (!search.equals("")) + deltaSearch = deltaSearch.replace("@" + search, ""); + String newContent = oldContent.substring(0, currentCursorPosition - searchLength); + newContent += deltaSearch; + newContent += "@" + account.getAcct() + " "; + int newPosition = newContent.length(); + if (currentCursorPosition < oldContent.length() ) + newContent += oldContent.substring(currentCursorPosition, oldContent.length()); + toot_content.setText(newContent); + toot_space_left.setText(String.valueOf(TootActivity.countLength(toot_content, toot_cw_content))); + toot_content.setSelection(newPosition); + AccountsSearchAdapter accountsListAdapter = new AccountsSearchAdapter(context, new ArrayList<>()); + toot_content.setThreshold(1); + toot_content.setAdapter(accountsListAdapter); + } + }); + } + } + } + } + + @Override + public void onRetrieveContact(APIResponse apiResponse) { + + } + + + @Override + public void onRetrieveSearchEmoji(List emojis) { + int currentCursorPosition = toot_content.getSelectionStart(); + int searchLength = 15; + if( emojis != null && emojis.size() > 0){ + EmojisSearchAdapter emojisSearchAdapter = new EmojisSearchAdapter(context, emojis); + toot_content.setThreshold(1); + toot_content.setAdapter(emojisSearchAdapter); + final String oldContent = toot_content.getText().toString(); + String[] searchA = oldContent.substring(0,currentCursorPosition).split(":"); + final String search = searchA[searchA.length-1]; + toot_content.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + String shortcode = emojis.get(position).getShortcode(); + String deltaSearch = ""; + if( currentCursorPosition-searchLength > 0 && currentCursorPosition < oldContent.length() ) + deltaSearch = oldContent.substring(currentCursorPosition-searchLength, currentCursorPosition); + else { + if( currentCursorPosition >= oldContent.length() ) + deltaSearch = oldContent.substring(currentCursorPosition-searchLength, oldContent.length()); + } + + if( !search.equals("")) + deltaSearch = deltaSearch.replace(":"+search,""); + String newContent = oldContent.substring(0,currentCursorPosition-searchLength); + newContent += deltaSearch; + newContent += ":" + shortcode + ": "; + int newPosition = newContent.length(); + if( currentCursorPosition < oldContent.length() ) + newContent += oldContent.substring(currentCursorPosition, oldContent.length()-1); + toot_content.setText(newContent); + toot_space_left.setText(String.valueOf(TootActivity.countLength(toot_content, toot_cw_content))); + toot_content.setSelection(newPosition); + EmojisSearchAdapter emojisSearchAdapter = new EmojisSearchAdapter(context, new ArrayList<>()); + toot_content.setThreshold(1); + toot_content.setAdapter(emojisSearchAdapter); + } + }); + } + } + + @Override + public void onRetrieveSearch(APIResponse apiResponse) { + if( apiResponse == null || apiResponse.getResults() == null) + return; + int searchLength = 15; + app.fedilab.android.client.Entities.Results results = apiResponse.getResults(); + int currentCursorPosition = toot_content.getSelectionStart(); + final List tags = results.getHashtags(); + if( tags != null && tags.size() > 0){ + TagsSearchAdapter tagsSearchAdapter = new TagsSearchAdapter(context, tags); + toot_content.setThreshold(1); + toot_content.setAdapter(tagsSearchAdapter); + final String oldContent = toot_content.getText().toString(); + if( oldContent.length() < currentCursorPosition) + return; + String[] searchA = oldContent.substring(0,currentCursorPosition).split("#"); + if( searchA.length < 1) + return; + final String search = searchA[searchA.length-1]; + toot_content.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + if( position >= tags.size() ) + return; + String tag = tags.get(position); + String deltaSearch = ""; + if( currentCursorPosition-searchLength > 0 && currentCursorPosition < oldContent.length() ) + deltaSearch = oldContent.substring(currentCursorPosition-searchLength, currentCursorPosition); + else { + if( currentCursorPosition >= oldContent.length() ) + deltaSearch = oldContent.substring(currentCursorPosition-searchLength, oldContent.length()); + } + + if( !search.equals("")) + deltaSearch = deltaSearch.replace("#"+search,""); + String newContent = oldContent.substring(0,currentCursorPosition-searchLength); + newContent += deltaSearch; + newContent += "#" + tag + " "; + int newPosition = newContent.length(); + if( currentCursorPosition < oldContent.length() ) + newContent += oldContent.substring(currentCursorPosition, oldContent.length()-1); + toot_content.setText(newContent); + toot_space_left.setText(String.valueOf(TootActivity.countLength(toot_content, toot_cw_content))); + toot_content.setSelection(newPosition); + TagsSearchAdapter tagsSearchAdapter = new TagsSearchAdapter(context, new ArrayList<>()); + toot_content.setThreshold(1); + toot_content.setAdapter(tagsSearchAdapter); + } + }); + } + } + private class ViewHolderEmpty extends RecyclerView.ViewHolder{ ViewHolderEmpty(View itemView) { @@ -2216,6 +2371,19 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct holder.quick_reply_text.getApplicationWindowToken(), InputMethodManager.SHOW_FORCED, 0); holder.quick_reply_text.requestFocus(); + EditText content_cw = new EditText(context); + content_cw.setText(status.getReblog()!=null?status.getReblog().getSpoiler_text():status.getSpoiler_text()); + TootActivity.manageMentions(context, userId, + holder.quick_reply_text,content_cw, holder.toot_space_left,status.getReblog()!=null?status.getReblog():status); + TextWatcher textWatcher = TootActivity.initializeTextWatcher(context, holder.quick_reply_text, content_cw, holder.toot_space_left, null, null, StatusListAdapter.this, StatusListAdapter.this, StatusListAdapter.this); + + toot_content =holder.quick_reply_text; + toot_cw_content = content_cw; + toot_space_left = holder.toot_space_left; + + if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON || MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA) + holder.status_content.addTextChangedListener(textWatcher); + } else { status.setShortReply(false); holder.quick_reply_container.setVisibility(View.GONE); @@ -3651,10 +3819,7 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct } - @Override - public void onRetrieveSearchEmoji(List emojis) { - } private void translateToot(Status status){ diff --git a/app/src/main/res/layout/drawer_status.xml b/app/src/main/res/layout/drawer_status.xml index bc7ae51f1..0a3e9392f 100644 --- a/app/src/main/res/layout/drawer_status.xml +++ b/app/src/main/res/layout/drawer_status.xml @@ -1104,7 +1104,7 @@ android:layout_marginTop="10dp" android:layout_weight="1" android:gravity="center_vertical" - android:text="500" + android:text="0" android:textColor="?colorAccent" app:layout_constraintEnd_toStartOf="@id/quick_reply_emoji" app:layout_constraintStart_toEndOf="@id/quick_reply_switch_to_full"