diff --git a/app/src/main/java/app/fedilab/android/BaseMainActivity.java b/app/src/main/java/app/fedilab/android/BaseMainActivity.java index 32dc4225..385f99d8 100644 --- a/app/src/main/java/app/fedilab/android/BaseMainActivity.java +++ b/app/src/main/java/app/fedilab/android/BaseMainActivity.java @@ -1145,6 +1145,19 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt .putString(getString(R.string.SET_TRANSLATE_BUTTON) + currentUserID + currentInstance, newTranslateButtonValue) .apply(); } + if (sharedpreferences.getString(getString(R.string.SET_QUOTE_BUTTON) + currentUserID + currentInstance, null) == null) { + boolean oldQuoteButtonPrefValue = + sharedpreferences.getBoolean(getString(R.string.SET_DISPLAY_QUOTE) + currentUserID + currentInstance, false); + String[] quoteButtonEntryValues = getResources().getStringArray(R.array.set_quote_button_entry_values); + String newQuoteButtonValue; + if (oldQuoteButtonPrefValue) + newQuoteButtonValue = quoteButtonEntryValues[0]; + else + newQuoteButtonValue = quoteButtonEntryValues[2]; + sharedpreferences.edit() + .putString(getString(R.string.SET_QUOTE_BUTTON) + currentUserID + currentInstance, newQuoteButtonValue) + .apply(); + } if (sharedpreferences.getString(getString(R.string.SET_LINK_PREVIEWS), null) == null) { boolean oldDisplayCardValue = sharedpreferences.getBoolean(getString(R.string.SET_DISPLAY_CARD), false); diff --git a/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/StatusAdapter.java b/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/StatusAdapter.java index b2cfa321..0321bd5f 100644 --- a/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/StatusAdapter.java +++ b/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/StatusAdapter.java @@ -49,6 +49,7 @@ import android.graphics.Bitmap; import android.graphics.PorterDuff; import android.graphics.Typeface; import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; @@ -62,6 +63,7 @@ import android.text.SpannableString; import android.text.TextUtils; import android.util.Log; import android.util.TypedValue; +import android.view.Gravity; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.MotionEvent; @@ -73,6 +75,7 @@ import android.widget.CheckBox; import android.widget.GridView; import android.widget.ImageView; import android.widget.LinearLayout; +import android.widget.PopupWindow; import android.widget.RadioButton; import android.widget.RelativeLayout; import android.widget.TextView; @@ -145,6 +148,7 @@ import app.fedilab.android.databinding.DrawerStatusPixelfedBinding; import app.fedilab.android.databinding.DrawerStatusReportBinding; import app.fedilab.android.databinding.LayoutMediaBinding; import app.fedilab.android.databinding.LayoutPollItemBinding; +import app.fedilab.android.databinding.PopupBoostQuoteBinding; import app.fedilab.android.mastodon.activities.ComposeActivity; import app.fedilab.android.mastodon.activities.ContextActivity; import app.fedilab.android.mastodon.activities.CustomSharingActivity; @@ -982,7 +986,7 @@ public class StatusAdapter extends RecyclerView.Adapter holder.binding.actionButtonFavorite.setInactiveImage(R.drawable.ic_round_star_border_24); holder.binding.actionButtonBookmark.setActiveImage(R.drawable.ic_round_bookmark_24); holder.binding.actionButtonBookmark.setInactiveImage(R.drawable.ic_round_bookmark_border_24); - if (displayQuote) { + if (quoteButton.equals(quoteButtonEntryValues[1])) { holder.binding.actionButtonBoost.setActiveImage(R.drawable.ic_quote_or_boost_active); holder.binding.actionButtonBoost.setInactiveImage(R.drawable.ic_quote_or_boost); } else { @@ -1226,47 +1230,48 @@ public class StatusAdapter extends RecyclerView.Adapter return true; }); holder.binding.actionButtonBoost.setOnClickListener(v -> { - if(displayQuote) { - PopupMenu popupMenu = new PopupMenu(context, v); - popupMenu.getMenuInflater().inflate(R.menu.menu_boost_or_quote, popupMenu.getMenu()); - if(statusToDeal.quote_approval != null && statusToDeal.quote_approval.current_user != null && statusToDeal.quote_approval.current_user.equalsIgnoreCase("denied") ) { - popupMenu.getMenu().findItem(R.id.action_quote).setEnabled(false); - } else { - popupMenu.getMenu().findItem(R.id.action_quote).setEnabled(true); - } - MenuItem reblogItem = popupMenu.getMenu().findItem(R.id.action_reblog); + if(quoteButton.equals(quoteButtonEntryValues[1])) { + LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + PopupWindow popupWindow = new PopupWindow(context); + PopupBoostQuoteBinding popupBoostQuoteBinding = PopupBoostQuoteBinding.inflate(layoutInflater); + popupWindow.setContentView(popupBoostQuoteBinding.getRoot()); + popupWindow.setWidth(LinearLayoutCompat.LayoutParams.WRAP_CONTENT); + popupWindow.setHeight(LinearLayoutCompat.LayoutParams.WRAP_CONTENT); + popupWindow.setFocusable(true); + popupWindow.setBackgroundDrawable(new ColorDrawable()); + popupWindow.setAnimationStyle(R.style.boostQuotePopupWindowAnimation); + + popupBoostQuoteBinding.boostButton.setIconSize(iconSize); + popupBoostQuoteBinding.quoteButton.setIconSize(iconSize); if(statusToDeal.reblogged) { - reblogItem.setTitle(R.string.action_unreblog); + popupBoostQuoteBinding.boostButton.setText(R.string.action_unreblog); + Helper.changeDrawableColor(context, popupBoostQuoteBinding.boostButton, R.color.boost_icon); } else { - reblogItem.setTitle(R.string.action_reblog); + popupBoostQuoteBinding.boostButton.setText(R.string.action_reblog); } - popupMenu.setOnMenuItemClickListener(item -> { - int itemId = item.getItemId(); - if (itemId == R.id.action_reblog) { - reblogTap(context, - v, - statusesVM, - searchVM, - holder, - adapter, - statusToDeal, - warnNoMedia, confirmBoost, remote); - return true; - } else if (itemId == R.id.action_quote) { - Intent intent = new Intent(context, ComposeActivity.class); - Bundle args = new Bundle(); - args.putSerializable(Helper.ARG_QUOTED_MESSAGE, statusToDeal); - new CachedBundle(context).insertBundle(args, Helper.getCurrentAccount(context), bundleId -> { - Bundle bundle = new Bundle(); - bundle.putLong(Helper.ARG_INTENT_ID, bundleId); - intent.putExtras(bundle); - context.startActivity(intent); - }); - return true; - } - return false; + popupBoostQuoteBinding.boostButton.setOnClickListener(v2 -> { + popupWindow.dismiss(); + reblogTap(context, + v, + statusesVM, + searchVM, + holder, + adapter, + statusToDeal, + warnNoMedia, confirmBoost, remote); }); - popupMenu.show(); + if(statusToDeal.quote_approval != null && statusToDeal.quote_approval.current_user != null && statusToDeal.quote_approval.current_user.equalsIgnoreCase("denied") ) { + popupBoostQuoteBinding.quoteButton.setEnabled(false); + } else { + popupBoostQuoteBinding.quoteButton.setOnClickListener(v2 -> { + quote(context, status); + popupWindow.dismiss(); + }); + } + + int[] actionButtonBoostLocation = new int[2]; + holder.binding.actionButtonBoost.getLocationInWindow(actionButtonBoostLocation); + popupWindow.showAtLocation(holder.binding.actionButtonBoost, Gravity.NO_GRAVITY, actionButtonBoostLocation[0], actionButtonBoostLocation[1]); } else { reblogTap(context, v, @@ -1280,6 +1285,13 @@ public class StatusAdapter extends RecyclerView.Adapter }); holder.binding.actionButtonBoost.setChecked(statusToDeal.reblogged); + // Quote button + if(quoteButton.equals(quoteButtonEntryValues[0])) { + holder.binding.actionButtonQuote.setVisibility(View.VISIBLE); + holder.binding.actionButtonQuote.setOnClickListener(v -> quote(context, status)); + } else { + holder.binding.actionButtonQuote.setVisibility(View.GONE); + } //---> FAVOURITE/UNFAVOURITE holder.binding.actionButtonFavorite.setOnLongClickListener(v -> { if (statusToDeal.visibility.equals("direct") || (statusToDeal.visibility.equals("private"))) { @@ -2574,6 +2586,18 @@ public class StatusAdapter extends RecyclerView.Adapter } + private static void quote(Context context, Status status) { + Intent intent = new Intent(context, ComposeActivity.class); + Bundle args = new Bundle(); + args.putSerializable(Helper.ARG_QUOTED_MESSAGE, status); + new CachedBundle(context).insertBundle(args, Helper.getCurrentAccount(context), bundleId -> { + Bundle bundle = new Bundle(); + bundle.putLong(Helper.ARG_INTENT_ID, bundleId); + intent.putExtras(bundle); + context.startActivity(intent); + }); + } + private static void clickMoreAction(Context context, StatusesVM statusesVM, StatusViewHolder holder, @@ -2589,6 +2613,9 @@ public class StatusAdapter extends RecyclerView.Adapter if (statusToDeal.visibility.equals("private") || statusToDeal.visibility.equals("direct")) { popup.getMenu().findItem(R.id.action_mention).setVisible(false); } + if (!quoteButton.equals(quoteButtonEntryValues[2])){ + popup.getMenu().findItem(R.id.action_quote).setVisible(false); + } if (statusToDeal.bookmarked) popup.getMenu().findItem(R.id.action_bookmark).setTitle(R.string.bookmark_remove); else @@ -2782,7 +2809,10 @@ public class StatusAdapter extends RecyclerView.Adapter } return true; - }else if (itemId == R.id.action_bookmark) { + } else if (itemId == R.id.action_quote) { + quote(context, statusToDeal); + return true; + } else if (itemId == R.id.action_bookmark) { if (statusToDeal.bookmarked) { statusesVM.unBookmark(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id).observe((LifecycleOwner) context, status1 -> Toasty.info(context, context.getString(R.string.status_unbookmarked)).show()); } else { diff --git a/app/src/main/java/app/fedilab/android/mastodon/ui/fragment/settings/FragmentTimelinesSettings.java b/app/src/main/java/app/fedilab/android/mastodon/ui/fragment/settings/FragmentTimelinesSettings.java index 0edc65a8..1a5c59af 100644 --- a/app/src/main/java/app/fedilab/android/mastodon/ui/fragment/settings/FragmentTimelinesSettings.java +++ b/app/src/main/java/app/fedilab/android/mastodon/ui/fragment/settings/FragmentTimelinesSettings.java @@ -94,10 +94,10 @@ public class FragmentTimelinesSettings extends PreferenceFragmentCompat implemen SET_TRANSLATE_BUTTON.setValue(value); } - SwitchPreferenceCompat SET_DISPLAY_QUOTE = findPreference(getString(R.string.SET_DISPLAY_QUOTE)); - if (SET_DISPLAY_QUOTE != null) { - boolean checked = sharedpreferences.getBoolean(getString(R.string.SET_DISPLAY_QUOTE) + MainActivity.currentUserID + MainActivity.currentInstance, true); - SET_DISPLAY_QUOTE.setChecked(checked); + ListPreference SET_QUOTE_BUTTON = findPreference(getString(R.string.SET_QUOTE_BUTTON)); + if (SET_QUOTE_BUTTON != null) { + String value = sharedpreferences.getString(getString(R.string.SET_QUOTE_BUTTON) + MainActivity.currentUserID + MainActivity.currentInstance, null); + SET_QUOTE_BUTTON.setValue(value); } SwitchPreferenceCompat SET_PIXELFED_PRESENTATION = findPreference(getString(R.string.SET_PIXELFED_PRESENTATION)); @@ -131,10 +131,10 @@ public class FragmentTimelinesSettings extends PreferenceFragmentCompat implemen editor.putString(getString(R.string.SET_TRANSLATE_BUTTON) + MainActivity.currentUserID + MainActivity.currentInstance, SET_TRANSLATE_BUTTON.getValue()); } } - if (key.compareToIgnoreCase(getString(R.string.SET_DISPLAY_QUOTE)) == 0) { - SwitchPreferenceCompat SET_DISPLAY_QUOTE = findPreference(getString(R.string.SET_DISPLAY_QUOTE)); - if (SET_DISPLAY_QUOTE != null) { - editor.putBoolean(getString(R.string.SET_DISPLAY_QUOTE) + MainActivity.currentUserID + MainActivity.currentInstance, SET_DISPLAY_QUOTE.isChecked()); + if (key.compareToIgnoreCase(getString(R.string.SET_QUOTE_BUTTON)) == 0) { + ListPreference SET_QUOTE_BUTTON = findPreference(getString(R.string.SET_QUOTE_BUTTON)); + if (SET_QUOTE_BUTTON != null) { + editor.putString(getString(R.string.SET_QUOTE_BUTTON) + MainActivity.currentUserID + MainActivity.currentInstance, SET_QUOTE_BUTTON.getValue()); } } if (key.compareToIgnoreCase(getString(R.string.SET_PIXELFED_PRESENTATION)) == 0) { diff --git a/app/src/main/res/anim/popup_window_enter.xml b/app/src/main/res/anim/popup_window_enter.xml new file mode 100644 index 00000000..ef594b6f --- /dev/null +++ b/app/src/main/res/anim/popup_window_enter.xml @@ -0,0 +1,14 @@ + + + + + diff --git a/app/src/main/res/anim/popup_window_exit.xml b/app/src/main/res/anim/popup_window_exit.xml new file mode 100644 index 00000000..86753773 --- /dev/null +++ b/app/src/main/res/anim/popup_window_exit.xml @@ -0,0 +1,14 @@ + + + + + diff --git a/app/src/main/res/layouts/mastodon/layout/drawer_status.xml b/app/src/main/res/layouts/mastodon/layout/drawer_status.xml index d7bd2a1c..4448d7de 100644 --- a/app/src/main/res/layouts/mastodon/layout/drawer_status.xml +++ b/app/src/main/res/layouts/mastodon/layout/drawer_status.xml @@ -778,6 +778,20 @@ + + diff --git a/app/src/main/res/layouts/mastodon/layout/popup_boost_quote.xml b/app/src/main/res/layouts/mastodon/layout/popup_boost_quote.xml new file mode 100644 index 00000000..0140cf57 --- /dev/null +++ b/app/src/main/res/layouts/mastodon/layout/popup_boost_quote.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/menus/mastodon/menu/option_toot.xml b/app/src/main/res/menus/mastodon/menu/option_toot.xml index b97b16e8..688cdbef 100644 --- a/app/src/main/res/menus/mastodon/menu/option_toot.xml +++ b/app/src/main/res/menus/mastodon/menu/option_toot.xml @@ -5,6 +5,10 @@ android:id="@+id/action_translate" android:title="@string/translate" app:showAsAction="never" /> + hide + + Dedicated button + Combine with boost button + In menu + Disable + + + dedicated + combine_with_boost + in_menu + disable + + Always show Hide in posts with media @@ -1313,6 +1326,7 @@ SET_DISPLAY_TRANSLATE SET_TRANSLATE_BUTTON + SET_QUOTE_BUTTON SET_POST_FORMAT SET_COMPOSE_LOCAL_ONLY @@ -2119,7 +2133,7 @@ Post format Icons for extra features If your instance does not accept some extra features, you can hide these icons - Display the \"Quote\" button + Quote button Display \"Reactions\" buttons Bubble Exclude visibility diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index b59ed315..56576cc0 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -309,4 +309,9 @@ + + diff --git a/app/src/main/res/xml/pref_timelines.xml b/app/src/main/res/xml/pref_timelines.xml index 40e2d7ba..d1dd459f 100644 --- a/app/src/main/res/xml/pref_timelines.xml +++ b/app/src/main/res/xml/pref_timelines.xml @@ -149,12 +149,13 @@ app:key="@string/SET_TRANSLATE_BUTTON" app:icon="@drawable/ic_baseline_translate_24" app:useSimpleSummaryProvider="true" /> - +