From fc7465148538a40ec657009cdc5eff0d4b90fbc5 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sun, 31 Jan 2021 17:06:22 +0100 Subject: [PATCH] Last fixes --- .../android/activities/BaseMainActivity.java | 339 +++++++-------- .../BasePixelfedComposeActivity.java | 401 +----------------- .../android/activities/HashTagActivity.java | 81 ++-- .../java/app/fedilab/android/client/API.java | 113 ++++- .../fedilab/android/client/PixelfedAPI.java | 2 +- .../drawers/BaseStatusListAdapter.java | 5 +- .../android/drawers/PixelfedListAdapter.java | 7 +- .../android/drawers/SliderAdapter.java | 32 +- .../fedilab/android/helper/BaseHelper.java | 6 +- .../main/res/menu/main_compose_pixelfed.xml | 15 - 10 files changed, 357 insertions(+), 644 deletions(-) diff --git a/app/src/main/java/app/fedilab/android/activities/BaseMainActivity.java b/app/src/main/java/app/fedilab/android/activities/BaseMainActivity.java index 8f16c3301..862e18587 100644 --- a/app/src/main/java/app/fedilab/android/activities/BaseMainActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/BaseMainActivity.java @@ -102,7 +102,6 @@ import app.fedilab.android.asynctasks.RetrieveMetaDataAsyncTask; import app.fedilab.android.asynctasks.RetrievePeertubeInformationAsyncTask; import app.fedilab.android.asynctasks.RetrieveRelationshipAsyncTask; import app.fedilab.android.asynctasks.RetrieveRemoteDataAsyncTask; -import app.fedilab.android.asynctasks.RetrieveStoriesAsyncTask; import app.fedilab.android.asynctasks.SyncTimelinesAsyncTask; import app.fedilab.android.asynctasks.UpdateAccountInfoAsyncTask; import app.fedilab.android.asynctasks.UpdateAccountInfoByIDAsyncTask; @@ -119,12 +118,10 @@ import app.fedilab.android.client.Entities.Status; import app.fedilab.android.client.Entities.TagTimeline; import app.fedilab.android.drawers.AccountSearchDevAdapter; import app.fedilab.android.fragments.DisplayAccountsFragment; -import app.fedilab.android.fragments.DisplayBookmarksPixelfedFragment; import app.fedilab.android.fragments.DisplayDraftsFragment; import app.fedilab.android.fragments.DisplayFavoritesPeertubeFragment; import app.fedilab.android.fragments.DisplayFiltersFragment; import app.fedilab.android.fragments.DisplayFollowRequestSentFragment; -import app.fedilab.android.fragments.DisplayHowToFragment; import app.fedilab.android.fragments.DisplayListsFragment; import app.fedilab.android.fragments.DisplayNotificationsFragment; import app.fedilab.android.fragments.DisplayPeertubeNotificationsFragment; @@ -204,6 +201,7 @@ public abstract class BaseMainActivity extends BaseActivity private View dialogReleaseNoteView; private List developers; + @SuppressLint("ApplySharedPref") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -610,12 +608,34 @@ public abstract class BaseMainActivity extends BaseActivity if (tab.getCustomView() != null) { if (viewPager.getAdapter() != null) { Fragment fragment = (Fragment) viewPager.getAdapter().instantiateItem(viewPager, tab.getPosition()); - if (fragment instanceof DisplayStatusFragment) { - DisplayStatusFragment displayStatusFragment = ((DisplayStatusFragment) fragment); - displayStatusFragment.scrollToTop(); - } else if (fragment instanceof DisplayNotificationsFragment) { - DisplayNotificationsFragment displayNotificationsFragment = ((DisplayNotificationsFragment) fragment); - displayNotificationsFragment.scrollToTop(); + DisplayStatusFragment displayStatusFragment; + if (tab.getPosition() == 0) { + if (fragment instanceof DisplayStatusFragment) { + displayStatusFragment = ((DisplayStatusFragment) fragment); + countNewStatus = 0; + updateHomeCounter(); + displayStatusFragment.scrollToTop(); + displayStatusFragment.updateLastReadToot(); + } + } else if (tab.getPosition() == 2) { + countNewNotifications = 0; + updateNotifCounter(); + } else { + View tabCustom = tab.getCustomView(); + if (tabCustom != null) { + TextView tabCountertCustom = tabCustom.findViewById(R.id.tab_counter); + if (tabCountertCustom != null) { + tabCountertCustom.setText(String.valueOf(0)); + tabCountertCustom.setVisibility(View.GONE); + } + } + if (fragment instanceof DisplayStatusFragment) { + displayStatusFragment = ((DisplayStatusFragment) fragment); + displayStatusFragment.scrollToTop(); + } else if (fragment instanceof DisplayNotificationsFragment) { + DisplayNotificationsFragment displayNotificationsFragment = ((DisplayNotificationsFragment) fragment); + displayNotificationsFragment.scrollToTop(); + } } } } @@ -781,16 +801,15 @@ public abstract class BaseMainActivity extends BaseActivity if (query.split("@").length > 1) { isAccount = true; } - if ((social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON || social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA) + Intent intent; + if ((social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON || social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA || social == UpdateAccountInfoAsyncTask.SOCIAL.PIXELFED) && !query.contains("http://") && !query.contains("https://") && !isAccount) { - Intent intent = new Intent(BaseMainActivity.this, SearchResultTabActivity.class); - intent.putExtra("search", query); - startActivity(intent); + intent = new Intent(BaseMainActivity.this, SearchResultTabActivity.class); } else { - Intent intent = new Intent(BaseMainActivity.this, SearchResultActivity.class); - intent.putExtra("search", query); - startActivity(intent); + intent = new Intent(BaseMainActivity.this, SearchResultActivity.class); } + intent.putExtra("search", query); + startActivity(intent); } else { Intent intent = new Intent(BaseMainActivity.this, HashTagActivity.class); @@ -937,166 +956,159 @@ public abstract class BaseMainActivity extends BaseActivity } popup.setOnMenuItemClickListener(item -> { - switch (item.getItemId()) { - case R.id.action_logout_account: - AlertDialog.Builder dialogBuilderLogoutAccount = new AlertDialog.Builder(BaseMainActivity.this, style); - dialogBuilderLogoutAccount.setMessage(getString(R.string.logout_account_confirmation, account.getUsername(), account.getInstance())); - dialogBuilderLogoutAccount.setPositiveButton(R.string.action_logout, (dialog, id) -> { - Helper.logoutCurrentUser(BaseMainActivity.this); - dialog.dismiss(); - }); - dialogBuilderLogoutAccount.setNegativeButton(R.string.cancel, (dialog, id) -> dialog.dismiss()); - AlertDialog alertDialogLogoutAccount = dialogBuilderLogoutAccount.create(); - alertDialogLogoutAccount.show(); - return true; - case R.id.action_privacy: - Intent intent14 = new Intent(BaseMainActivity.this, PrivacyActivity.class); - startActivity(intent14); - return true; - case R.id.action_about_instance: - intent14 = new Intent(BaseMainActivity.this, InstanceActivity.class); - startActivity(intent14); - return true; - case R.id.action_send_invitation: - if (instanceClass != null) { - if (instanceClass.isRegistration()) { - Intent sendIntent = new Intent(Intent.ACTION_SEND); - String extra_text = getString(R.string.join_instance, Helper.getLiveInstance(BaseMainActivity.this), - "https://f-droid.org/en/packages/fr.gouv.etalab.mastodon/", - "https://play.google.com/store/apps/details?id=app.fedilab.android", - "https://fedilab.app/registration_helper/" + Helper.getLiveInstance(BaseMainActivity.this)); - sendIntent.putExtra(Intent.EXTRA_TEXT, extra_text); - sendIntent.setType("text/plain"); - startActivity(Intent.createChooser(sendIntent, getString(R.string.share_with))); - } else { - Toasty.info(BaseMainActivity.this, getString(R.string.registration_closed), Toast.LENGTH_SHORT).show(); - } + int itemId = item.getItemId(); + if (itemId == R.id.action_logout_account) { + AlertDialog.Builder dialogBuilderLogoutAccount = new AlertDialog.Builder(BaseMainActivity.this, style); + dialogBuilderLogoutAccount.setMessage(getString(R.string.logout_account_confirmation, account.getUsername(), account.getInstance())); + dialogBuilderLogoutAccount.setPositiveButton(R.string.action_logout, (dialog, id) -> { + Helper.logoutCurrentUser(BaseMainActivity.this); + dialog.dismiss(); + }); + dialogBuilderLogoutAccount.setNegativeButton(R.string.cancel, (dialog, id) -> dialog.dismiss()); + AlertDialog alertDialogLogoutAccount = dialogBuilderLogoutAccount.create(); + alertDialogLogoutAccount.show(); + return true; + } else if (itemId == R.id.action_privacy) { + Intent intent14 = new Intent(BaseMainActivity.this, PrivacyActivity.class); + startActivity(intent14); + return true; + } else if (itemId == R.id.action_about_instance) { + Intent intent14; + intent14 = new Intent(BaseMainActivity.this, InstanceActivity.class); + startActivity(intent14); + return true; + } else if (itemId == R.id.action_send_invitation) { + if (instanceClass != null) { + if (instanceClass.isRegistration()) { + Intent sendIntent = new Intent(Intent.ACTION_SEND); + String extra_text = getString(R.string.join_instance, Helper.getLiveInstance(BaseMainActivity.this), + "https://f-droid.org/en/packages/fr.gouv.etalab.mastodon/", + "https://play.google.com/store/apps/details?id=app.fedilab.android", + "https://fedilab.app/registration_helper/" + Helper.getLiveInstance(BaseMainActivity.this)); + sendIntent.putExtra(Intent.EXTRA_TEXT, extra_text); + sendIntent.setType("text/plain"); + startActivity(Intent.createChooser(sendIntent, getString(R.string.share_with))); + } else { + Toasty.info(BaseMainActivity.this, getString(R.string.registration_closed), Toast.LENGTH_SHORT).show(); } - return true; - case R.id.action_cache: - new Helper.CacheTask(BaseMainActivity.this); - return true; - case R.id.action_size: - final SharedPreferences sharedpreferences1 = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE); - int textSize = sharedpreferences1.getInt(Helper.SET_TEXT_SIZE, 110); - int iconSize = sharedpreferences1.getInt(Helper.SET_ICON_SIZE, 130); + } + return true; + } else if (itemId == R.id.action_cache) { + new Helper.CacheTask(BaseMainActivity.this); + return true; + } else if (itemId == R.id.action_size) { + final SharedPreferences sharedpreferences1 = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE); + int textSize = sharedpreferences1.getInt(Helper.SET_TEXT_SIZE, 110); + int iconSize = sharedpreferences1.getInt(Helper.SET_ICON_SIZE, 130); - AlertDialog.Builder builder = new AlertDialog.Builder(BaseMainActivity.this, style); - builder.setTitle(R.string.text_size); + AlertDialog.Builder builder = new AlertDialog.Builder(BaseMainActivity.this, style); + builder.setTitle(R.string.text_size); - View popup_quick_settings = getLayoutInflater().inflate(R.layout.popup_text_size, new LinearLayout(BaseMainActivity.this), false); - builder.setView(popup_quick_settings); + View popup_quick_settings = getLayoutInflater().inflate(R.layout.popup_text_size, new LinearLayout(BaseMainActivity.this), false); + builder.setView(popup_quick_settings); - SeekBar set_text_size = popup_quick_settings.findViewById(R.id.set_text_size); - SeekBar set_icon_size = popup_quick_settings.findViewById(R.id.set_icon_size); - final TextView set_text_size_value = popup_quick_settings.findViewById(R.id.set_text_size_value); - final TextView set_icon_size_value = popup_quick_settings.findViewById(R.id.set_icon_size_value); - set_text_size_value.setText(String.format("%s%%", textSize)); - set_icon_size_value.setText(String.format("%s%%", iconSize)); + SeekBar set_text_size = popup_quick_settings.findViewById(R.id.set_text_size); + SeekBar set_icon_size = popup_quick_settings.findViewById(R.id.set_icon_size); + final TextView set_text_size_value = popup_quick_settings.findViewById(R.id.set_text_size_value); + final TextView set_icon_size_value = popup_quick_settings.findViewById(R.id.set_icon_size_value); + set_text_size_value.setText(String.format("%s%%", textSize)); + set_icon_size_value.setText(String.format("%s%%", iconSize)); - set_text_size.setMax(20); - set_icon_size.setMax(20); + set_text_size.setMax(20); + set_icon_size.setMax(20); - set_text_size.setProgress(((textSize - 80) / 5)); - set_icon_size.setProgress(((iconSize - 80) / 5)); + set_text_size.setProgress(((textSize - 80) / 5)); + set_icon_size.setProgress(((iconSize - 80) / 5)); - set_text_size.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - } + set_text_size.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + } - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - } + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + } - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - int value = 80 + progress * 5; - set_text_size_value.setText(String.format("%s%%", value)); - SharedPreferences.Editor editor = sharedpreferences1.edit(); - editor.putInt(Helper.SET_TEXT_SIZE, value); - editor.apply(); - } - }); - set_icon_size.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - } + int value = 80 + progress * 5; + set_text_size_value.setText(String.format("%s%%", value)); + SharedPreferences.Editor editor = sharedpreferences1.edit(); + editor.putInt(Helper.SET_TEXT_SIZE, value); + editor.apply(); + } + }); + set_icon_size.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + } - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - } + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + } - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - int value = 80 + progress * 5; - set_icon_size_value.setText(String.format("%s%%", value)); - SharedPreferences.Editor editor = sharedpreferences1.edit(); - editor.putInt(Helper.SET_ICON_SIZE, value); - editor.apply(); - } - }); - builder.setPositiveButton(R.string.validate, (dialog, which) -> { - BaseMainActivity.this.recreate(); - dialog.dismiss(); - }) - .setIcon(android.R.drawable.ic_dialog_alert) - .show(); - return true; - case R.id.action_proxy: - intent14 = new Intent(BaseMainActivity.this, ProxyActivity.class); - startActivity(intent14); - return true; - case R.id.action_export: - if (Build.VERSION.SDK_INT >= 23) { - if (ContextCompat.checkSelfPermission(BaseMainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { - ActivityCompat.requestPermissions(BaseMainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, Helper.EXTERNAL_STORAGE_REQUEST_CODE); - } else { - Intent backupIntent = new Intent(BaseMainActivity.this, BackupStatusService.class); - startService(backupIntent); - } + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + int value = 80 + progress * 5; + set_icon_size_value.setText(String.format("%s%%", value)); + SharedPreferences.Editor editor = sharedpreferences1.edit(); + editor.putInt(Helper.SET_ICON_SIZE, value); + editor.apply(); + } + }); + builder.setPositiveButton(R.string.validate, (dialog, which) -> { + BaseMainActivity.this.recreate(); + dialog.dismiss(); + }) + .setIcon(android.R.drawable.ic_dialog_alert) + .show(); + return true; + } else if (itemId == R.id.action_proxy) { + Intent intent14; + intent14 = new Intent(BaseMainActivity.this, ProxyActivity.class); + startActivity(intent14); + return true; + } else if (itemId == R.id.action_export) { + if (Build.VERSION.SDK_INT >= 23) { + if (ContextCompat.checkSelfPermission(BaseMainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(BaseMainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, Helper.EXTERNAL_STORAGE_REQUEST_CODE); } else { Intent backupIntent = new Intent(BaseMainActivity.this, BackupStatusService.class); startService(backupIntent); } + } else { + Intent backupIntent = new Intent(BaseMainActivity.this, BackupStatusService.class); + startService(backupIntent); + } + return true; + } else if (itemId == R.id.action_import_data) { + Intent intent14; + if (ContextCompat.checkSelfPermission(BaseMainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != + PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(BaseMainActivity.this, + new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, + TootActivity.MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE); return true; - - case R.id.action_import_data: - if (ContextCompat.checkSelfPermission(BaseMainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != - PackageManager.PERMISSION_GRANTED) { - ActivityCompat.requestPermissions(BaseMainActivity.this, - new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, - TootActivity.MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE); + } + intent14 = new Intent(Intent.ACTION_GET_CONTENT); + intent14.addCategory(Intent.CATEGORY_OPENABLE); + intent14.setType("*/*"); + String[] mimetypes = {"*/*"}; + intent14.putExtra(Intent.EXTRA_MIME_TYPES, mimetypes); + startActivityForResult(intent14, PICK_IMPORT); + return true; + } else if (itemId == R.id.action_export_data) { + if (Build.VERSION.SDK_INT >= 23) { + if (ContextCompat.checkSelfPermission(BaseMainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(BaseMainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, Helper.EXTERNAL_STORAGE_REQUEST_CODE); return true; } - intent14 = new Intent(Intent.ACTION_GET_CONTENT); - intent14.addCategory(Intent.CATEGORY_OPENABLE); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - intent14.setType("*/*"); - String[] mimetypes = {"*/*"}; - intent14.putExtra(Intent.EXTRA_MIME_TYPES, mimetypes); - startActivityForResult(intent14, PICK_IMPORT); - } else { - intent14.setType("*/*"); - Intent pickIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); - Intent chooserIntent = Intent.createChooser(intent14, getString(R.string.toot_select_import)); - chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[]{pickIntent}); - startActivityForResult(chooserIntent, PICK_IMPORT); - } - return true; - case R.id.action_export_data: - if (Build.VERSION.SDK_INT >= 23) { - if (ContextCompat.checkSelfPermission(BaseMainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { - ActivityCompat.requestPermissions(BaseMainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, Helper.EXTERNAL_STORAGE_REQUEST_CODE); - return true; - } - } - Sqlite.exportDB(BaseMainActivity.this); - return true; - default: - return true; + } + Sqlite.exportDB(BaseMainActivity.this); + return true; } + return true; }); popup.show(); }); @@ -1477,10 +1489,7 @@ public abstract class BaseMainActivity extends BaseActivity if (url == null) return; Matcher matcher; - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) - matcher = Patterns.WEB_URL.matcher(url); - else - matcher = Helper.urlPattern.matcher(url); + matcher = Patterns.WEB_URL.matcher(url); boolean isUrl = false; while (matcher.find()) { isUrl = true; @@ -1503,10 +1512,7 @@ public abstract class BaseMainActivity extends BaseActivity is and strip that out into sharedText. */ Matcher matcher; - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) - matcher = Patterns.WEB_URL.matcher(sharedText); - else - matcher = Helper.urlPattern.matcher(sharedText); + matcher = Patterns.WEB_URL.matcher(sharedText); while (matcher.find()) { int matchStart = matcher.start(1); int matchEnd = matcher.end(); @@ -1558,10 +1564,7 @@ public abstract class BaseMainActivity extends BaseActivity return; } Matcher matcher; - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) - matcher = Patterns.WEB_URL.matcher(url); - else - matcher = Helper.urlPattern.matcher(url); + matcher = Patterns.WEB_URL.matcher(url); boolean isUrl = false; while (matcher.find()) { isUrl = true; diff --git a/app/src/main/java/app/fedilab/android/activities/BasePixelfedComposeActivity.java b/app/src/main/java/app/fedilab/android/activities/BasePixelfedComposeActivity.java index 30c9d85d4..a070caf6e 100644 --- a/app/src/main/java/app/fedilab/android/activities/BasePixelfedComposeActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/BasePixelfedComposeActivity.java @@ -31,7 +31,6 @@ import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.Paint; import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -44,7 +43,6 @@ import android.text.Html; import android.text.InputType; import android.text.SpannableString; import android.text.TextWatcher; -import android.text.format.DateFormat; import android.text.style.ForegroundColorSpan; import android.util.Patterns; import android.view.LayoutInflater; @@ -56,7 +54,6 @@ import android.view.inputmethod.InputMethodManager; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.CheckBox; -import android.widget.DatePicker; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; @@ -64,11 +61,9 @@ import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.ScrollView; import android.widget.TextView; -import android.widget.TimePicker; import android.widget.Toast; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AlertDialog; import androidx.core.app.ActivityCompat; @@ -77,9 +72,6 @@ import androidx.core.content.FileProvider; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.preference.PreferenceManager; -import com.bumptech.glide.Glide; -import com.bumptech.glide.request.target.CustomTarget; -import com.bumptech.glide.request.transition.Transition; import com.smarteist.autoimageslider.IndicatorAnimations; import com.smarteist.autoimageslider.SliderAnimations; import com.smarteist.autoimageslider.SliderView; @@ -107,25 +99,19 @@ import java.io.IOException; import java.io.InputStream; import java.lang.ref.WeakReference; import java.net.MalformedURLException; -import java.text.Normalizer; import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Calendar; import java.util.Date; -import java.util.GregorianCalendar; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Objects; -import java.util.Random; -import java.util.TimeZone; import java.util.UUID; import java.util.regex.Matcher; import java.util.regex.Pattern; import app.fedilab.android.BuildConfig; import app.fedilab.android.R; -import app.fedilab.android.asynctasks.PostActionAsyncTask; import app.fedilab.android.asynctasks.PostStatusAsyncTask; import app.fedilab.android.asynctasks.RetrieveEmojiAsyncTask; import app.fedilab.android.asynctasks.RetrieveSearchAccountsAsyncTask; @@ -155,14 +141,11 @@ import app.fedilab.android.interfaces.OnRetrieveAttachmentInterface; import app.fedilab.android.interfaces.OnRetrieveEmojiInterface; import app.fedilab.android.interfaces.OnRetrieveSearcAccountshInterface; import app.fedilab.android.interfaces.OnRetrieveSearchInterface; -import app.fedilab.android.jobs.ScheduledTootsSyncJob; import app.fedilab.android.sqlite.AccountDAO; import app.fedilab.android.sqlite.Sqlite; import app.fedilab.android.sqlite.StatusStoredDAO; import es.dmoral.toasty.Toasty; -import static app.fedilab.android.helper.Helper.ALPHA; -import static app.fedilab.android.helper.Helper.MORSE; import static app.fedilab.android.helper.Helper.THEME_LIGHT; import static app.fedilab.android.helper.Helper.countWithEmoji; @@ -205,10 +188,7 @@ public abstract class BasePixelfedComposeActivity extends BaseActivity implement private Account accountReply; private Account account; private boolean removed; - private boolean restoredScheduled; private int style; - private StoredStatus scheduledstatus; - private boolean isScheduled; private int max_media_count; private UploadServiceSingleBroadcastReceiver uploadReceiver; private UpdateAccountInfoAsyncTask.SOCIAL social; @@ -257,7 +237,6 @@ public abstract class BasePixelfedComposeActivity extends BaseActivity implement String patternEmoji = "^(.|\\s)*(:([\\w_]+))$"; final Pattern ePattern = Pattern.compile(patternEmoji); final int[] currentCursorPosition = {toot_content.getSelectionStart()}; - final String[] newContent = {null}; final int[] searchLength = {searchDeep}; TextWatcher textw; textw = new TextWatcher() { @@ -273,89 +252,6 @@ public abstract class BasePixelfedComposeActivity extends BaseActivity implement @Override public void afterTextChanged(Editable s) { - if (autocomplete) { - toot_content.removeTextChangedListener(this); - Thread thread = new Thread() { - @Override - public void run() { - String fedilabHugsTrigger = ":fedilab_hugs:"; - String fedilabMorseTrigger = ":fedilab_morse:"; - - if (s.toString().contains(fedilabHugsTrigger)) { - newContent[0] = s.toString().replaceAll(fedilabHugsTrigger, ""); - int currentLength = countLength(social, toot_content); - int toFill = 150 - currentLength; - if (toFill <= 0) { - return; - } - StringBuilder hugs = new StringBuilder(); - for (int i = 0; i < toFill; i++) { - hugs.append(new String(Character.toChars(0x1F917))); - } - - Handler mainHandler = new Handler(Looper.getMainLooper()); - - Runnable myRunnable = () -> { - 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(social, toot_content))); - }; - mainHandler.post(myRunnable); - } else if (s.toString().contains(fedilabMorseTrigger)) { - newContent[0] = s.toString().replaceAll(fedilabMorseTrigger, "").trim(); - List mentions = new ArrayList<>(); - String mentionPattern = "@[a-z0-9_]+(@[a-z0-9.\\-]+[a-z0-9]+)?"; - final Pattern mPattern = Pattern.compile(mentionPattern, Pattern.CASE_INSENSITIVE); - Matcher matcherMentions = mPattern.matcher(newContent[0]); - while (matcherMentions.find()) { - mentions.add(matcherMentions.group()); - } - for (String mention : mentions) { - newContent[0] = newContent[0].replace(mention, ""); - } - newContent[0] = Normalizer.normalize(newContent[0], Normalizer.Form.NFD); - newContent[0] = newContent[0].replaceAll("[^\\p{ASCII}]", ""); - - HashMap ALPHA_TO_MORSE = new HashMap<>(); - for (int i = 0; i < ALPHA.length && i < MORSE.length; i++) { - ALPHA_TO_MORSE.put(ALPHA[i], MORSE[i]); - } - StringBuilder builder = new StringBuilder(); - String[] words = newContent[0].trim().split(" "); - - for (String word : words) { - for (int i = 0; i < word.length(); i++) { - String morse = ALPHA_TO_MORSE.get(word.substring(i, i + 1).toLowerCase()); - builder.append(morse).append(" "); - } - - builder.append(" "); - } - newContent[0] = ""; - for (String mention : mentions) { - newContent[0] += mention + " "; - } - newContent[0] += builder.toString(); - - Handler mainHandler = new Handler(Looper.getMainLooper()); - - Runnable myRunnable = () -> { - toot_content.setText(newContent[0]); - toot_content.setSelection(toot_content.getText().length()); - autocomplete = false; - toot_space_left.setText(String.valueOf(countLength(social, toot_content))); - }; - mainHandler.post(myRunnable); - } - } - }; - thread.start(); - return; - } - if (toot_content.getSelectionStart() != 0) currentCursorPosition[0] = toot_content.getSelectionStart(); if (s.toString().length() == 0) @@ -370,22 +266,6 @@ public abstract class BasePixelfedComposeActivity extends BaseActivity implement 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; - } - - String patternM = "^(.|\\s)*(:fedilab_morse:)$"; - final Pattern mPattern = Pattern.compile(patternM); - Matcher mm = mPattern.matcher((s.toString().substring(currentCursorPosition[0] - searchLength[0], currentCursorPosition[0]))); - if (mm.matches()) { - autocomplete = true; - return; - } String[] searchInArray = (s.toString().substring(currentCursorPosition[0] - searchLength[0], currentCursorPosition[0])).split("\\s"); if (searchInArray.length < 1) { return; @@ -541,7 +421,7 @@ public abstract class BasePixelfedComposeActivity extends BaseActivity implement String scheme = sharedpreferences.getString(Helper.SET_ONION_SCHEME + Helper.getLiveInstance(activity), "https"); String token = sharedpreferences.getString(Helper.PREF_KEY_OAUTH_TOKEN, null); int maxUploadRetryTimes = sharedpreferences.getInt(Helper.MAX_UPLOAD_IMG_RETRY_TIMES, 3); - String url = scheme + "://" + Helper.getLiveInstance(activity) + "/api/pixelfed/v1/media"; + String url = scheme + "://" + Helper.getLiveInstance(activity) + "/api/compose/v0/media/upload"; if (pixelfedStory) { url = scheme + "://" + Helper.getLiveInstance(activity) + "/api/stories/v0/add"; } @@ -551,15 +431,18 @@ public abstract class BasePixelfedComposeActivity extends BaseActivity implement uploadConfig.getProgress().message = activity.getString(R.string.uploading); uploadConfig.getCompleted().autoClear = true; MultipartUploadRequest request = new MultipartUploadRequest(activity, uploadId, url); - String cookie = token.split("\\|")[1]; - request.addHeader("cookie", cookie); - String[] tokens = token.split("\\|")[0].split(";"); - request.addHeader("x-xsrf-token", tokens[0].replace("X-XSRF-TOKEN= ", "")); - request.addHeader("x-csrf-token", tokens[1].replace("X-CSRF-TOKEN= ", "")); - request.setNotificationConfig(uploadConfig); - request.addFileToUpload(uri.toString().replace("file://", ""), "file"); - request.addParameter("filename", fileName).setMaxRetries(maxUploadRetryTimes); - request.startUpload(); + String cookie; + if (token != null) { + cookie = token.split("\\|")[1]; + request.addHeader("cookie", cookie); + String[] tokens = token.split("\\|")[0].split(";"); + request.addHeader("x-xsrf-token", tokens[0].replace("X-XSRF-TOKEN= ", "")); + request.addHeader("x-csrf-token", tokens[1].replace("X-CSRF-TOKEN= ", "")); + request.setNotificationConfig(uploadConfig); + request.addFileToUpload(uri.toString().replace("file://", ""), "file"); + request.addParameter("filename", fileName).setMaxRetries(maxUploadRetryTimes); + request.startUpload(); + } } catch (MalformedURLException | FileNotFoundException e) { e.printStackTrace(); } @@ -662,7 +545,6 @@ public abstract class BasePixelfedComposeActivity extends BaseActivity implement //By default the toot is not restored so the id -1 is defined currentToId = -1; - restoredScheduled = false; toot_it = findViewById(R.id.toot_it); attachments = new ArrayList<>(); imageSlider = findViewById(R.id.imageSlider); @@ -685,7 +567,6 @@ public abstract class BasePixelfedComposeActivity extends BaseActivity implement drawer_layout = findViewById(R.id.drawer_layout); ImageButton toot_emoji = findViewById(R.id.toot_emoji); LinearLayout bottom_bar_tooting = findViewById(R.id.bottom_bar_tooting); - isScheduled = false; if (sharedpreferences.getBoolean(Helper.SET_DISPLAY_EMOJI, false)) { displayEmojiPopup(); } else { @@ -720,7 +601,6 @@ public abstract class BasePixelfedComposeActivity extends BaseActivity implement SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); restored = -1; if (b != null) { - scheduledstatus = b.getParcelable("storedStatus"); String accountReplyToken = b.getString("accountReplyToken", null); accountReply = null; if (accountReplyToken != null) { @@ -731,7 +611,6 @@ public abstract class BasePixelfedComposeActivity extends BaseActivity implement } removed = b.getBoolean("removed"); visibility = b.getString("visibility", null); - restoredScheduled = b.getBoolean("restoredScheduled", false); // ACTION_SEND route if (b.getInt("uriNumberMast", 0) == 1) { Uri fileUri = b.getParcelable("sharedUri"); @@ -752,12 +631,7 @@ public abstract class BasePixelfedComposeActivity extends BaseActivity implement if (!sharedUri.isEmpty()) { uploadSharedImage(sharedUri); } - if (scheduledstatus != null) - toot_it.setText(R.string.modify); - if (restoredScheduled) { - toot_it.setVisibility(View.GONE); - invalidateOptionsMenu(); - } + String userIdReply, instanceReply; if (accountReply == null) { userIdReply = sharedpreferences.getString(Helper.PREF_KEY_ID, null); @@ -807,7 +681,7 @@ public abstract class BasePixelfedComposeActivity extends BaseActivity implement toot_visibility.setOnClickListener(v -> tootVisibilityDialog()); - toot_it.setOnClickListener(v -> sendToot(null)); + toot_it.setOnClickListener(v -> sendToot()); pickup_picture.setOnClickListener(v -> { @@ -855,9 +729,6 @@ public abstract class BasePixelfedComposeActivity extends BaseActivity implement toot_content.addTextChangedListener(textWatcher); - if (scheduledstatus != null) - restoreServerSchedule(scheduledstatus.getStatus()); - if (restored != -1) { restoreToot(restored); } @@ -1080,7 +951,7 @@ public abstract class BasePixelfedComposeActivity extends BaseActivity implement if (error != null) { Toasty.error(BasePixelfedComposeActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show(); } else { - Toasty.success(BasePixelfedComposeActivity.this, getString(R.string.toot_scheduled), Toast.LENGTH_LONG).show(); + Toasty.success(BasePixelfedComposeActivity.this, getString(R.string.toot_sent), Toast.LENGTH_LONG).show(); resetForNextToot(); } } @@ -1142,17 +1013,6 @@ public abstract class BasePixelfedComposeActivity extends BaseActivity implement @Override public boolean onOptionsItemSelected(@NotNull MenuItem item) { - int style; - SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, 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; - } - int itemId = item.getItemId(); if (itemId == android.R.id.home) { finish(); @@ -1160,137 +1020,29 @@ public abstract class BasePixelfedComposeActivity extends BaseActivity implement } else if (itemId == R.id.action_photo_camera) { dispatchTakePictureIntent(); return true; - } else if (itemId == R.id.action_store) { - storeToot(true, true); - return true; - } else if (itemId == R.id.action_schedule) { - if (toot_content.getText().toString().trim().length() == 0) { - Toasty.error(BasePixelfedComposeActivity.this, getString(R.string.toot_error_no_content), Toast.LENGTH_LONG).show(); - return true; - } - AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(BasePixelfedComposeActivity.this, style); - LayoutInflater inflater = this.getLayoutInflater(); - View dialogView = inflater.inflate(R.layout.datetime_picker, new LinearLayout(BasePixelfedComposeActivity.this), false); - dialogBuilder.setView(dialogView); - final AlertDialog alertDialog = dialogBuilder.create(); - - final DatePicker datePicker = dialogView.findViewById(R.id.date_picker); - final TimePicker timePicker = dialogView.findViewById(R.id.time_picker); - if (DateFormat.is24HourFormat(BasePixelfedComposeActivity.this)) - timePicker.setIs24HourView(true); - Button date_time_cancel = dialogView.findViewById(R.id.date_time_cancel); - final ImageButton date_time_previous = dialogView.findViewById(R.id.date_time_previous); - final ImageButton date_time_next = dialogView.findViewById(R.id.date_time_next); - final ImageButton date_time_set = dialogView.findViewById(R.id.date_time_set); - - //Buttons management - date_time_cancel.setOnClickListener(v -> alertDialog.dismiss()); - date_time_next.setOnClickListener(v -> { - datePicker.setVisibility(View.GONE); - timePicker.setVisibility(View.VISIBLE); - date_time_previous.setVisibility(View.VISIBLE); - date_time_next.setVisibility(View.GONE); - date_time_set.setVisibility(View.VISIBLE); - }); - date_time_previous.setOnClickListener(v -> { - datePicker.setVisibility(View.VISIBLE); - timePicker.setVisibility(View.GONE); - date_time_previous.setVisibility(View.GONE); - date_time_next.setVisibility(View.VISIBLE); - date_time_set.setVisibility(View.GONE); - }); - date_time_set.setOnClickListener(v -> { - int hour, minute; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - hour = timePicker.getHour(); - minute = timePicker.getMinute(); - } else { - hour = timePicker.getCurrentHour(); - minute = timePicker.getCurrentMinute(); - } - Calendar calendar = new GregorianCalendar(datePicker.getYear(), - datePicker.getMonth(), - datePicker.getDayOfMonth(), - hour, - minute); - final long[] time = {calendar.getTimeInMillis()}; - - if ((time[0] - new Date().getTime()) < 60000) { - Toasty.warning(BasePixelfedComposeActivity.this, getString(R.string.toot_scheduled_date), Toast.LENGTH_LONG).show(); - } else { - AlertDialog.Builder builderSingle = new AlertDialog.Builder(BasePixelfedComposeActivity.this, style); - builderSingle.setTitle(getString(R.string.choose_schedule)); - builderSingle.setNegativeButton(R.string.device_schedule, (dialog, which) -> { - deviceSchedule(time[0]); - dialog.dismiss(); - }); - builderSingle.setPositiveButton(R.string.server_schedule, (dialog, which) -> { - int offset = TimeZone.getDefault().getRawOffset(); - calendar.add(Calendar.MILLISECOND, -offset); - final String date = Helper.dateToString(new Date(calendar.getTimeInMillis())); - serverSchedule(date); - }); - builderSingle.show(); - alertDialog.dismiss(); - } - }); - alertDialog.show(); - return true; } return super.onOptionsItemSelected(item); } - private void sendToot(String timestamp) { + private void sendToot() { toot_it.setEnabled(false); if (toot_content.getText().toString().trim().length() == 0 && attachments.size() == 0) { Toasty.error(BasePixelfedComposeActivity.this, getString(R.string.toot_error_no_content), Toast.LENGTH_LONG).show(); toot_it.setEnabled(true); return; } - - String tootContent = toot_content.getText().toString().trim(); - Status toot = new Status(); toot.setSensitive(isSensitive); toot.setVisibility(visibility); toot.setMedia_attachments(attachments); toot.setContent(BasePixelfedComposeActivity.this, tootContent); - if (timestamp == null) - if (scheduledstatus == null) - new PostStatusAsyncTask(BasePixelfedComposeActivity.this, social, account, toot, BasePixelfedComposeActivity.this); - else { - toot.setScheduled_at(Helper.dateToString(scheduledstatus.getScheduled_date())); - scheduledstatus.setStatus(toot); - isScheduled = true; - new PostActionAsyncTask(BasePixelfedComposeActivity.this, API.StatusAction.DELETESCHEDULED, scheduledstatus, BasePixelfedComposeActivity.this); - new PostStatusAsyncTask(BasePixelfedComposeActivity.this, social, account, toot, BasePixelfedComposeActivity.this); - } - else { - toot.setScheduled_at(timestamp); - new PostStatusAsyncTask(BasePixelfedComposeActivity.this, social, account, toot, BasePixelfedComposeActivity.this); - } + new PostStatusAsyncTask(BasePixelfedComposeActivity.this, social, account, toot, BasePixelfedComposeActivity.this); } - private void serverSchedule(String time) { - sendToot(time); - isScheduled = true; - resetForNextToot(); - } - - private void deviceSchedule(long time) { - //Store the toot as draft first - storeToot(false, false); - isScheduled = true; - //Schedules the toot - ScheduledTootsSyncJob.schedule(BasePixelfedComposeActivity.this, currentToId, time); - resetForNextToot(); - } - - private void resetForNextToot() { //Clear content toot_content.setText(""); @@ -1308,20 +1060,12 @@ public abstract class BasePixelfedComposeActivity extends BaseActivity implement isSensitive = false; toot_sensitive.setVisibility(View.GONE); currentToId = -1; - Toasty.info(BasePixelfedComposeActivity.this, getString(R.string.toot_scheduled), Toast.LENGTH_LONG).show(); + Toasty.info(BasePixelfedComposeActivity.this, getString(R.string.toot_sent), Toast.LENGTH_LONG).show(); } @Override public boolean onCreateOptionsMenu(@NotNull Menu menu) { getMenuInflater().inflate(R.menu.main_compose_pixelfed, menu); - if (restored != -1) { - MenuItem itemRestore = menu.findItem(R.id.action_restore); - if (itemRestore != null) - itemRestore.setVisible(false); - MenuItem itemSchedule = menu.findItem(R.id.action_schedule); - if (restoredScheduled || pixelfed_story.isChecked()) - itemSchedule.setVisible(false); - } SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE); int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK); if (theme == THEME_LIGHT) { @@ -1478,8 +1222,6 @@ public abstract class BasePixelfedComposeActivity extends BaseActivity implement } } - final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE); - if (apiResponse.getError() == null || apiResponse.getError().getStatusCode() != -33) { if (restored != -1) { SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); @@ -1506,13 +1248,7 @@ public abstract class BasePixelfedComposeActivity extends BaseActivity implement toot_sensitive.setVisibility(View.GONE); currentToId = -1; if (apiResponse.getError() == null) { - if (scheduledstatus == null && !isScheduled) { - boolean display_confirm = sharedpreferences.getBoolean(Helper.SET_DISPLAY_CONFIRM, true); - if (display_confirm) { - Toasty.success(BasePixelfedComposeActivity.this, getString(R.string.toot_sent), Toast.LENGTH_LONG).show(); - } - } else - Toasty.success(BasePixelfedComposeActivity.this, getString(R.string.toot_scheduled), Toast.LENGTH_LONG).show(); + Toasty.success(BasePixelfedComposeActivity.this, getString(R.string.toot_sent), Toast.LENGTH_LONG).show(); } else { if (apiResponse.getError().getStatusCode() == -33) Toasty.info(BasePixelfedComposeActivity.this, getString(R.string.toast_toot_saved_error), Toast.LENGTH_LONG).show(); @@ -1805,103 +1541,6 @@ public abstract class BasePixelfedComposeActivity extends BaseActivity implement imageSlider.setCurrentPagePosition(position); } - private void restoreServerSchedule(Status status) { - - attachments = status.getMedia_attachments(); - String content = status.getContent(); - Pattern mentionLink = Pattern.compile("(<\\s?a\\s?href=\"https?://([\\da-z.-]+\\.[a-z.]{2,10})/(@[/\\w._-]*)\"\\s?[^.]*<\\s?/\\s?a\\s?>)"); - Matcher matcher = mentionLink.matcher(content); - if (matcher.find()) { - content = matcher.replaceAll("$3@$2"); - } - if (removed) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) - content = Html.fromHtml(content, Html.FROM_HTML_MODE_LEGACY).toString(); - else - content = Html.fromHtml(content).toString(); - } - if (attachments != null && attachments.size() > 0) { - for (final Attachment attachment : attachments) { - String url = attachment.getPreview_url(); - if (url == null || url.trim().equals("")) - url = attachment.getUrl(); - final ImageView imageView = new ImageView(BasePixelfedComposeActivity.this); - Random rand = new Random(); - int n = rand.nextInt(10000000); - imageView.setId(n); - attachment.setViewId(n); - - LinearLayout.LayoutParams imParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT); - imParams.setMargins(20, 5, 20, 5); - imParams.height = (int) Helper.convertDpToPixel(100, BasePixelfedComposeActivity.this); - imageView.setAdjustViewBounds(true); - imageView.setScaleType(ImageView.ScaleType.FIT_XY); - - Glide.with(imageView.getContext()) - .asBitmap() - .load(url) - .into(new CustomTarget() { - @Override - public void onResourceReady(@NonNull Bitmap resource, Transition transition) { - imageView.setImageBitmap(resource); - } - - @Override - public void onLoadCleared(@Nullable Drawable placeholder) { - - } - }); - imageView.setTag(attachment.getId()); - - imageView.setOnLongClickListener(view -> false); - if (attachments.size() < max_media_count) - upload_media.setEnabled(true); - toot_sensitive.setVisibility(View.VISIBLE); - } - } else { - imageSlider.setVisibility(View.GONE); - pickup_picture.setVisibility(View.VISIBLE); - } - //Sensitive content - toot_sensitive.setChecked(status.isSensitive()); - toot_content.setText(content); - toot_space_left.setText(String.valueOf(countLength(social, toot_content))); - toot_content.setSelection(toot_content.getText().length()); - switch (status.getVisibility()) { - case "public": - visibility = "public"; - toot_visibility.setImageResource(R.drawable.ic_public_toot); - break; - case "unlisted": - visibility = "unlisted"; - toot_visibility.setImageResource(R.drawable.ic_lock_open_toot); - break; - case "private": - visibility = "private"; - toot_visibility.setImageResource(R.drawable.ic_lock_outline_toot); - break; - case "direct": - visibility = "direct"; - toot_visibility.setImageResource(R.drawable.ic_mail_outline_toot); - break; - } - - if (title != null) { - if (social == UpdateAccountInfoAsyncTask.SOCIAL.GNU) - title.setText(getString(R.string.queet_title)); - else - title.setText(getString(R.string.toot_title)); - } else { - if (social == UpdateAccountInfoAsyncTask.SOCIAL.GNU) - setTitle(R.string.queet_title); - else - setTitle(R.string.toot_title); - } - invalidateOptionsMenu(); - initialContent = toot_content.getText().toString(); - toot_space_left.setText(String.valueOf(countLength(social, toot_content))); - } - private void storeToot(boolean message, boolean forced) { //Nothing to store here.... String currentContent; diff --git a/app/src/main/java/app/fedilab/android/activities/HashTagActivity.java b/app/src/main/java/app/fedilab/android/activities/HashTagActivity.java index a03042353..7807ffb16 100644 --- a/app/src/main/java/app/fedilab/android/activities/HashTagActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/HashTagActivity.java @@ -14,7 +14,6 @@ * see . */ package app.fedilab.android.activities; - import android.content.Intent; import android.content.SharedPreferences; import android.database.sqlite.SQLiteDatabase; @@ -22,16 +21,12 @@ import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.widget.RelativeLayout; import android.widget.Toast; -import androidx.appcompat.widget.Toolbar; + import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; - -import com.google.android.material.floatingactionbutton.FloatingActionButton; import org.jetbrains.annotations.NotNull; @@ -40,10 +35,13 @@ import java.util.List; import app.fedilab.android.R; import app.fedilab.android.asynctasks.RetrieveFeedsAsyncTask; +import app.fedilab.android.asynctasks.UpdateAccountInfoAsyncTask; import app.fedilab.android.client.APIResponse; import app.fedilab.android.client.Entities.Status; import app.fedilab.android.client.Entities.StatusDrawerParams; import app.fedilab.android.client.Entities.StoredStatus; +import app.fedilab.android.databinding.ActivityHashtagBinding; +import app.fedilab.android.drawers.PixelfedListAdapter; import app.fedilab.android.drawers.StatusListAdapter; import app.fedilab.android.helper.Helper; import app.fedilab.android.interfaces.OnRetrieveFeedsInterface; @@ -62,14 +60,14 @@ public class HashTagActivity extends BaseActivity implements OnRetrieveFeedsInte public static int position; private StatusListAdapter statusListAdapter; + private PixelfedListAdapter pixelfedListAdapter; private String max_id; private List statuses; - private RelativeLayout mainLoader, nextElementLoader, textviewNoAction; private boolean firstLoad; - private SwipeRefreshLayout swipeRefreshLayout; private String tag; private int tootsPerPage; private boolean flag_loading = false; + private ActivityHashtagBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { @@ -89,9 +87,10 @@ public class HashTagActivity extends BaseActivity implements OnRetrieveFeedsInte setTheme(R.style.AppThemeDark_NoActionBar); } - setContentView(R.layout.activity_hashtag); - Toolbar toolbar = findViewById(R.id.toolbar); - setSupportActionBar(toolbar); + binding = ActivityHashtagBinding.inflate(getLayoutInflater()); + View viewRoot = binding.getRoot(); + setContentView(viewRoot); + setSupportActionBar(binding.toolbar); if (getSupportActionBar() != null) getSupportActionBar().setDisplayHomeAsUpEnabled(true); @@ -106,17 +105,19 @@ public class HashTagActivity extends BaseActivity implements OnRetrieveFeedsInte flag_loading = true; firstLoad = true; boolean isOnWifi = Helper.isOnWIFI(HashTagActivity.this); - swipeRefreshLayout = findViewById(R.id.swipeContainer); int c1 = getResources().getColor(R.color.cyanea_accent); int c2 = getResources().getColor(R.color.cyanea_primary_dark); int c3 = getResources().getColor(R.color.cyanea_primary); - swipeRefreshLayout.setProgressBackgroundColorSchemeColor(c3); - swipeRefreshLayout.setColorSchemeColors( + binding.swipeContainer.setProgressBackgroundColorSchemeColor(c3); + binding.swipeContainer.setColorSchemeColors( c1, c2, c1 ); - FloatingActionButton toot = findViewById(R.id.toot); - toot.setOnClickListener(v -> { + if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PIXELFED) { + binding.toot.hide(); + } + + binding.toot.setOnClickListener(v -> { Intent intentToot = new Intent(HashTagActivity.this, TootActivity.class); Bundle val = new Bundle(); StoredStatus storedStatus = new StoredStatus(); @@ -129,23 +130,25 @@ public class HashTagActivity extends BaseActivity implements OnRetrieveFeedsInte startActivity(intentToot); }); - toolbar.setBackgroundColor(ContextCompat.getColor(HashTagActivity.this, R.color.cyanea_primary)); - final RecyclerView lv_status = findViewById(R.id.lv_status); + binding.toot.setBackgroundColor(ContextCompat.getColor(HashTagActivity.this, R.color.cyanea_primary)); + tootsPerPage = sharedpreferences.getInt(Helper.SET_TOOT_PER_PAGE, Helper.TOOTS_PER_PAGE); - mainLoader = findViewById(R.id.loader); - nextElementLoader = findViewById(R.id.loading_next_status); - textviewNoAction = findViewById(R.id.no_action); - mainLoader.setVisibility(View.VISIBLE); - nextElementLoader.setVisibility(View.GONE); StatusDrawerParams statusDrawerParams = new StatusDrawerParams(); statusDrawerParams.setType(RetrieveFeedsAsyncTask.Type.TAG); statusDrawerParams.setTargetedId(null); statusDrawerParams.setOnWifi(isOnWifi); statusDrawerParams.setStatuses(this.statuses); - statusListAdapter = new StatusListAdapter(statusDrawerParams); - lv_status.setAdapter(statusListAdapter); + + if (MainActivity.social != UpdateAccountInfoAsyncTask.SOCIAL.PIXELFED) { + statusListAdapter = new StatusListAdapter(statusDrawerParams); + binding.lvStatus.setAdapter(statusListAdapter); + } else { + pixelfedListAdapter = new PixelfedListAdapter(statusDrawerParams); + binding.lvStatus.setAdapter(pixelfedListAdapter); + } + setTitle(String.format("#%s", tag)); - swipeRefreshLayout.setOnRefreshListener(() -> { + binding.swipeContainer.setOnRefreshListener(() -> { max_id = null; statuses = new ArrayList<>(); firstLoad = true; @@ -154,8 +157,8 @@ public class HashTagActivity extends BaseActivity implements OnRetrieveFeedsInte }); final LinearLayoutManager mLayoutManager; mLayoutManager = new LinearLayoutManager(this); - lv_status.setLayoutManager(mLayoutManager); - lv_status.addOnScrollListener(new RecyclerView.OnScrollListener() { + binding.lvStatus.setLayoutManager(mLayoutManager); + binding.lvStatus.addOnScrollListener(new RecyclerView.OnScrollListener() { public void onScrolled(@NotNull RecyclerView recyclerView, int dx, int dy) { if (dy > 0) { int visibleItemCount = mLayoutManager.getChildCount(); @@ -166,10 +169,10 @@ public class HashTagActivity extends BaseActivity implements OnRetrieveFeedsInte flag_loading = true; new RetrieveFeedsAsyncTask(HashTagActivity.this, RetrieveFeedsAsyncTask.Type.TAG, tag, null, max_id, HashTagActivity.this); - nextElementLoader.setVisibility(View.VISIBLE); + binding.loadingNextStatus.setVisibility(View.VISIBLE); } } else { - nextElementLoader.setVisibility(View.GONE); + binding.loadingNextStatus.setVisibility(View.GONE); } } } @@ -190,7 +193,7 @@ public class HashTagActivity extends BaseActivity implements OnRetrieveFeedsInte SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); List searchInDb = new SearchDAO(HashTagActivity.this, db).getSearchByKeyword(tag.trim()); - if (searchInDb != null && searchInDb.size() > 0) { + if (searchInDb != null && searchInDb.size() > 0 || MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PIXELFED) { menu.findItem(R.id.action_pin).setVisible(false); } return true; @@ -218,8 +221,8 @@ public class HashTagActivity extends BaseActivity implements OnRetrieveFeedsInte @Override public void onRetrieveFeeds(APIResponse apiResponse) { - mainLoader.setVisibility(View.GONE); - nextElementLoader.setVisibility(View.GONE); + binding.loader.setVisibility(View.GONE); + binding.loadingNextStatus.setVisibility(View.GONE); if (apiResponse == null || apiResponse.getError() != null) { if (apiResponse != null) Toasty.error(HashTagActivity.this, apiResponse.getError().getError(), Toast.LENGTH_LONG).show(); @@ -229,18 +232,22 @@ public class HashTagActivity extends BaseActivity implements OnRetrieveFeedsInte } List statuses = apiResponse.getStatuses(); if (firstLoad && (statuses == null || statuses.size() == 0)) - textviewNoAction.setVisibility(View.VISIBLE); + binding.noAction.setVisibility(View.VISIBLE); else - textviewNoAction.setVisibility(View.GONE); + binding.noAction.setVisibility(View.GONE); if (statuses != null && statuses.size() > 1) max_id = statuses.get(statuses.size() - 1).getId(); else max_id = null; if (statuses != null) { this.statuses.addAll(statuses); - statusListAdapter.notifyDataSetChanged(); + if (statusListAdapter != null) { + statusListAdapter.notifyDataSetChanged(); + } else if (pixelfedListAdapter != null) { + pixelfedListAdapter.notifyDataSetChanged(); + } } - swipeRefreshLayout.setRefreshing(false); + binding.swipeContainer.setRefreshing(false); firstLoad = false; flag_loading = statuses != null && statuses.size() < tootsPerPage; } diff --git a/app/src/main/java/app/fedilab/android/client/API.java b/app/src/main/java/app/fedilab/android/client/API.java index 269d9c173..dd312924c 100644 --- a/app/src/main/java/app/fedilab/android/client/API.java +++ b/app/src/main/java/app/fedilab/android/client/API.java @@ -1408,6 +1408,32 @@ public class API { return parseAccountResponse(resobj, true); } + + /** + * Parse json response an unique account + * + * @param resobj JSONObject + * @return Account + */ + private static Account parseAccountPixelfedSearchResponse(JSONObject resobj) { + + Account account = new Account(); + try { + account.setId(resobj.getJSONObject("entity").getString("id")); + account.setFollowing(resobj.getJSONObject("entity").getBoolean("following")); + account.setAvatar(resobj.getString("avatar")); + account.setAvatar_static(resobj.getString("avatar")); + account.setDisplay_name(resobj.getString("name")); + account.setUsername(resobj.getString("value")); + account.setNote(""); + account.setAcct(resobj.getString("value")); + account.setUrl(resobj.getString("url")); + account.setStatuses_count(resobj.getJSONObject("entity").getInt("post_count")); + } catch (Exception ignored) { + } + return account; + } + /** * Parse json response an unique account * @@ -3996,11 +4022,25 @@ public class API { } catch (UnsupportedEncodingException ignored) { } String response; - if (instance == null) - response = httpsConnection.get(getAbsoluteUrl(String.format("/timelines/tag/%s", query)), 10, params, prefKeyOauthTokenT); - else - response = httpsConnection.get(getAbsoluteUrlRemote(instance, String.format("/timelines/tag/%s", query)), 10, params, null); - statuses = parseStatuses(context, new JSONArray(response)); + if (MainActivity.social != UpdateAccountInfoAsyncTask.SOCIAL.PIXELFED) { + if (instance == null) + response = httpsConnection.get(getAbsoluteUrl(String.format("/timelines/tag/%s", query)), 10, params, prefKeyOauthTokenT); + else + response = httpsConnection.get(getAbsoluteUrlRemote(instance, String.format("/timelines/tag/%s", query)), 10, params, null); + statuses = parseStatuses(context, new JSONArray(response)); + } else { + //Parse for pixelfed + params = new HashMap<>(); + params.put("hashtag", tag); + response = httpsConnection.get(getAbsoluteUr2l("/discover/tag"), 10, params, null); + JSONArray tags = new JSONObject(response).getJSONArray("tags"); + statuses = new ArrayList<>(); + for (int i = 0; i < tags.length(); i++) { + Status status = parseStatuses(context, tags.getJSONObject(i).getJSONObject("status")); + statuses.add(status); + } + } + setStatusesMaxId(httpsConnection, statuses); } catch (HttpsConnection.HttpsConnectionException e) { setError(e.getStatusCode(), e); @@ -4894,7 +4934,7 @@ public class API { jsonObject.addProperty("item", status.getIn_reply_to_id()); jsonObject.addProperty("sensitive", status.isSensitive()); } else { - url = "https://" + Helper.getLiveInstance(context) + "/api/local/status/compose"; + url = "https://" + Helper.getLiveInstance(context) + "/api/compose/v0/publish"; jsonObject.addProperty("caption", status.getContent()); jsonObject.addProperty("comments_disabled", false); jsonObject.addProperty("cw", status.isSensitive()); @@ -5290,7 +5330,18 @@ public class API { params.put("resolve", "true"); try { HttpsConnection httpsConnection = new HttpsConnection(context, this.instance); - String response = httpsConnection.get(getAbsoluteUr2l("/search"), 10, params, prefKeyOauthTokenT); + String response; + if (MainActivity.social != UpdateAccountInfoAsyncTask.SOCIAL.PIXELFED) { + response = httpsConnection.get(getAbsoluteUr2l("/search"), 10, params, prefKeyOauthTokenT); + } else { + String searchPixelfed; + try { + searchPixelfed = "q=" + URLEncoder.encode(query, "UTF-8"); + } catch (UnsupportedEncodingException e) { + searchPixelfed = "q=" + query; + } + response = httpsConnection.get(Helper.getLiveInstanceWithProtocol(context) + "/api/search?" + searchPixelfed + "&src=metro&v=2&scope=all", 10, null, prefKeyOauthTokenT); + } results = parseResultsResponse(new JSONObject(response)); apiResponse.setSince_id(httpsConnection.getSince_id()); apiResponse.setMax_id(httpsConnection.getMax_id()); @@ -5801,8 +5852,15 @@ public class API { Results results = new Results(); try { - results.setAccounts(parseAccountResponse(resobj.getJSONArray("accounts"))); - results.setStatuses(parseStatuses(context, resobj.getJSONArray("statuses"))); + if (resobj.has("accounts")) { + results.setAccounts(parseAccountResponse(resobj.getJSONArray("accounts"))); + } + if (resobj.has("profiles")) { + results.setAccounts(parseAccountPixelfedSearchResponse(resobj.getJSONArray("profiles"))); + } + if (resobj.has("statuses")) { + results.setStatuses(parseStatuses(context, resobj.getJSONArray("statuses"))); + } results.setTrends(parseTrends(resobj.getJSONArray("hashtags"))); results.setHashtags(parseTags(resobj.getJSONArray("hashtags"))); } catch (JSONException e) { @@ -5840,7 +5898,11 @@ public class API { try { if (jsonArray.get(i) instanceof JSONObject) { - list_tmp.add(jsonArray.getJSONObject(i).getString("name")); + if (jsonArray.getJSONObject(i).has("name")) { + list_tmp.add(jsonArray.getJSONObject(i).getString("name")); + } else if (jsonArray.getJSONObject(i).has("value")) { + list_tmp.add(jsonArray.getJSONObject(i).getString("value")); + } } else { list_tmp.add(jsonArray.getString(i)); } @@ -5933,7 +5995,11 @@ public class API { private Trends parseTrends(JSONObject resobj) { Trends trend = new Trends(); try { - trend.setName(resobj.getString("name")); + if (resobj.has("name") && !resobj.isNull("name")) { + trend.setName(resobj.getString("name")); + } else if (resobj.has("value")) { + trend.setName(resobj.getString("value")); + } trend.setUrl(resobj.getString("url")); List historyList = new ArrayList<>(); if (resobj.has("history")) { @@ -6318,6 +6384,30 @@ public class API { return accounts; } + + /** + * Parse json response for list of accounts + * + * @param jsonArray JSONArray + * @return List + */ + private List parseAccountPixelfedSearchResponse(JSONArray jsonArray) { + + List accounts = new ArrayList<>(); + try { + int i = 0; + while (i < jsonArray.length()) { + JSONObject resobj = jsonArray.getJSONObject(i); + Account account = parseAccountPixelfedSearchResponse(resobj); + accounts.add(account); + i++; + } + } catch (JSONException e) { + setDefaultError(e); + } + return accounts; + } + /** * Parse json response an unique relationship * @@ -6494,6 +6584,7 @@ public class API { } + private String getAbsoluteUr2l(String action) { return Helper.instanceWithProtocol(this.context, this.instance) + "/api/v2" + action; } diff --git a/app/src/main/java/app/fedilab/android/client/PixelfedAPI.java b/app/src/main/java/app/fedilab/android/client/PixelfedAPI.java index c45f8e2fe..4c32b88e8 100644 --- a/app/src/main/java/app/fedilab/android/client/PixelfedAPI.java +++ b/app/src/main/java/app/fedilab/android/client/PixelfedAPI.java @@ -257,7 +257,7 @@ public class PixelfedAPI { try { HttpsConnection httpsConnection = new HttpsConnection(context, this.instance); - String response = httpsConnection.postJson(getAbsoluteUrl("/delete/" + id), 30, new JsonObject(), prefKeyOauthTokenT); + httpsConnection.delete(getAbsoluteUrl("/delete/" + id), 30, null, prefKeyOauthTokenT); } catch (HttpsConnection.HttpsConnectionException e) { setError(e.getStatusCode(), e); e.printStackTrace(); diff --git a/app/src/main/java/app/fedilab/android/drawers/BaseStatusListAdapter.java b/app/src/main/java/app/fedilab/android/drawers/BaseStatusListAdapter.java index bd61bf4b3..6b42a2434 100644 --- a/app/src/main/java/app/fedilab/android/drawers/BaseStatusListAdapter.java +++ b/app/src/main/java/app/fedilab/android/drawers/BaseStatusListAdapter.java @@ -201,7 +201,7 @@ public abstract class BaseStatusListAdapter extends RecyclerView.Adapter statuses; + private List statuses; private final boolean isOnWifi; private final BaseStatusListAdapter statusListAdapter; private final String targetedId; @@ -246,6 +246,9 @@ public abstract class BaseStatusListAdapter extends RecyclerView.Adapter(); + } isOnWifi = statusDrawerParams.isOnWifi(); statusListAdapter = this; type = statusDrawerParams.getType(); diff --git a/app/src/main/java/app/fedilab/android/drawers/PixelfedListAdapter.java b/app/src/main/java/app/fedilab/android/drawers/PixelfedListAdapter.java index 3af9f6487..2382c97c1 100644 --- a/app/src/main/java/app/fedilab/android/drawers/PixelfedListAdapter.java +++ b/app/src/main/java/app/fedilab/android/drawers/PixelfedListAdapter.java @@ -208,6 +208,9 @@ public class PixelfedListAdapter extends RecyclerView.Adapter comments = this.statuses.get(position).getComments(); + if (comments == null) { + comments = new ArrayList<>(); + } comments.add(comments.size(), apiResponse.getStatuses().get(0)); this.statuses.get(position).setComments(comments); notifyStatusChanged(this.statuses.get(position)); @@ -694,10 +697,6 @@ public class PixelfedListAdapter extends RecyclerView.Adapter { String userIdOwner = sharedpreferences.getString(Helper.PREF_KEY_ID, null); if (attachments.size() > position) { - if (isStory && userId.compareTo(userIdOwner) == 0) { - new Thread(() -> { - new PixelfedAPI(contextWeakReference.get()).deleteStory(attachments.get(position).getId()); - Handler mainHandler = new Handler(Looper.getMainLooper()); - Runnable myRunnable = () -> { - attachments.remove(attachments.get(position)); - sliderAdapter.notifyDataSetChanged(); - if (contextWeakReference.get() instanceof PixelfedComposeActivity) { - ((PixelfedComposeActivity) contextWeakReference.get()).redraw(); - } - }; - mainHandler.post(myRunnable); - }).start(); + Attachment attachment = attachments.get(position); + if (isStory && userIdOwner != null && userId.compareTo(userIdOwner) == 0 && attachments.size() > position) { + new Thread(() -> new PixelfedAPI(contextWeakReference.get()).deleteStory(attachment.getId())).start(); } - } else { - attachments.remove(attachments.get(position)); + attachments.remove(attachment); sliderAdapter.notifyDataSetChanged(); - if (contextWeakReference.get() instanceof PixelfedComposeActivity) { - ((PixelfedComposeActivity) contextWeakReference.get()).redraw(); + if (contextWeakReference.get() instanceof BasePixelfedComposeActivity) { + ((BasePixelfedComposeActivity) contextWeakReference.get()).redraw(); } } dialog12.dismiss(); diff --git a/app/src/main/java/app/fedilab/android/helper/BaseHelper.java b/app/src/main/java/app/fedilab/android/helper/BaseHelper.java index 64f29ff19..0286f2310 100644 --- a/app/src/main/java/app/fedilab/android/helper/BaseHelper.java +++ b/app/src/main/java/app/fedilab/android/helper/BaseHelper.java @@ -756,6 +756,9 @@ public class BaseHelper { * @return String */ public static String shortDateToString(Date date) { + if (date == null) { + date = new Date(); + } SimpleDateFormat df = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault()); return df.format(date); } @@ -1459,7 +1462,8 @@ public class BaseHelper { MenuItem nav_blocked_domains = menu.findItem(R.id.nav_blocked_domains); if (nav_blocked_domains != null) nav_blocked_domains.setVisible(false); - + menu.findItem(R.id.nav_blocked).setVisible(false); + menu.findItem(R.id.nav_muted).setVisible(false); } else if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.FRIENDICA || BaseMainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.GNU || BaseMainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON || BaseMainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA) { MenuItem itemCom = menu.findItem(R.id.nav_peertube_comm); diff --git a/app/src/main/res/menu/main_compose_pixelfed.xml b/app/src/main/res/menu/main_compose_pixelfed.xml index 66d08ccf4..b2ec18928 100644 --- a/app/src/main/res/menu/main_compose_pixelfed.xml +++ b/app/src/main/res/menu/main_compose_pixelfed.xml @@ -6,19 +6,4 @@ android:icon="@drawable/ic_photo_camera" android:title="@string/camera" app:showAsAction="ifRoom" /> - - -