diff --git a/app/src/main/java/app/fedilab/android/activities/ComposeActivity.java b/app/src/main/java/app/fedilab/android/activities/ComposeActivity.java index 88addf67..5ff370ba 100644 --- a/app/src/main/java/app/fedilab/android/activities/ComposeActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/ComposeActivity.java @@ -104,7 +104,7 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana public static final int TAKE_PHOTO = 5600; private final Timer timer = new Timer(); private List statusList; - private Status statusReply, statusMention; + private Status statusReply, statusMention, statusQuoted; private StatusDraft statusDraft; private ComposeAdapter composeAdapter; private boolean promptSaveDraft; @@ -465,6 +465,7 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana Bundle b = getIntent().getExtras(); if (b != null) { statusReply = (Status) b.getSerializable(Helper.ARG_STATUS_REPLY); + statusQuoted = (Status) b.getSerializable(Helper.ARG_QUOTED_MESSAGE); statusDraft = (StatusDraft) b.getSerializable(Helper.ARG_STATUS_DRAFT); scheduledStatus = (ScheduledStatus) b.getSerializable(Helper.ARG_STATUS_SCHEDULED); statusReplyId = b.getString(Helper.ARG_STATUS_REPLY_ID); @@ -557,6 +558,9 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana List statusDraftList = new ArrayList<>(); Status status = new Status(); status.id = Helper.generateIdString(); + if (statusQuoted != null) { + status.quote_id = statusQuoted.id; + } statusDraftList.add(status); if (statusReplyId != null && statusDraft != null) {//Delete and redraft @@ -647,6 +651,18 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana binding.recyclerView.setAdapter(composeAdapter); statusesVM.getContext(currentInstance, BaseMainActivity.currentToken, statusReply.id) .observe(ComposeActivity.this, this::initializeContextView); + } else if (statusQuoted != null) { + statusList.add(statusQuoted); + int statusCount = statusList.size(); + statusDraftList.get(0).quote_id = statusQuoted.id; + //StatusDraftList at this point should only have one element + statusList.addAll(statusDraftList); + composeAdapter = new ComposeAdapter(statusList, statusCount, account, accountMention, visibility, editMessageId); + composeAdapter.manageDrafts = this; + composeAdapter.promptDraftListener = this; + LinearLayoutManager mLayoutManager = new LinearLayoutManager(ComposeActivity.this); + binding.recyclerView.setLayoutManager(mLayoutManager); + binding.recyclerView.setAdapter(composeAdapter); } else { //Compose without replying statusList.addAll(statusDraftList); diff --git a/app/src/main/java/app/fedilab/android/client/endpoints/MastodonStatusesService.java b/app/src/main/java/app/fedilab/android/client/endpoints/MastodonStatusesService.java index cf8613b4..bec0146e 100644 --- a/app/src/main/java/app/fedilab/android/client/endpoints/MastodonStatusesService.java +++ b/app/src/main/java/app/fedilab/android/client/endpoints/MastodonStatusesService.java @@ -59,7 +59,8 @@ public interface MastodonStatusesService { @Field("sensitive") Boolean sensitive, @Field("spoiler_text") String spoiler_text, @Field("visibility") String visibility, - @Field("language") String language + @Field("language") String language, + @Field("quote_id") String quote_id ); @GET("statuses/{id}/source") diff --git a/app/src/main/java/app/fedilab/android/client/entities/api/Status.java b/app/src/main/java/app/fedilab/android/client/entities/api/Status.java index 222c393a..a5db6c57 100644 --- a/app/src/main/java/app/fedilab/android/client/entities/api/Status.java +++ b/app/src/main/java/app/fedilab/android/client/entities/api/Status.java @@ -48,6 +48,8 @@ public class Status implements Serializable, Cloneable { public String spoiler_text; @SerializedName("text") public String text; + @SerializedName("quote_id") + public String quote_id; @SerializedName("visibility") public String visibility; @SerializedName("language") @@ -76,6 +78,8 @@ public class Status implements Serializable, Cloneable { public String content; @SerializedName("reblog") public Status reblog; + @SerializedName("quote") + public Status quote; @SerializedName("application") public App application; @SerializedName("account") diff --git a/app/src/main/java/app/fedilab/android/helper/Helper.java b/app/src/main/java/app/fedilab/android/helper/Helper.java index dc415779..cb02fdb9 100644 --- a/app/src/main/java/app/fedilab/android/helper/Helper.java +++ b/app/src/main/java/app/fedilab/android/helper/Helper.java @@ -226,6 +226,7 @@ public class Helper { public static final String ARG_STATUS_DRAFT_ID = "ARG_STATUS_DRAFT_ID"; public static final String ARG_STATUS_REPLY = "ARG_STATUS_REPLY"; public static final String ARG_MENTION_BOOSTER = "ARG_MENTION_BOOSTER"; + public static final String ARG_QUOTED_MESSAGE = "ARG_QUOTED_MESSAGE"; public static final String ARG_STATUS_REPLY_ID = "ARG_STATUS_REPLY_ID"; public static final String ARG_ACCOUNT = "ARG_ACCOUNT"; public static final String ARG_ACCOUNT_ID = "ARG_ACCOUNT_ID"; diff --git a/app/src/main/java/app/fedilab/android/jobs/ComposeWorker.java b/app/src/main/java/app/fedilab/android/jobs/ComposeWorker.java index de565b87..776130e9 100644 --- a/app/src/main/java/app/fedilab/android/jobs/ComposeWorker.java +++ b/app/src/main/java/app/fedilab/android/jobs/ComposeWorker.java @@ -221,7 +221,7 @@ public class ComposeWorker extends Worker { if (dataPost.scheduledDate == null) { if (dataPost.statusEditId == null) { statusCall = mastodonStatusesService.createStatus(null, dataPost.token, statuses.get(i).text, attachmentIds, poll_options, poll_expire_in, - poll_multiple, poll_hide_totals, in_reply_to_status, statuses.get(i).sensitive, statuses.get(i).spoilerChecked ? statuses.get(i).spoiler_text : null, statuses.get(i).visibility.toLowerCase(), language); + poll_multiple, poll_hide_totals, in_reply_to_status, statuses.get(i).sensitive, statuses.get(i).spoilerChecked ? statuses.get(i).spoiler_text : null, statuses.get(i).visibility.toLowerCase(), language, statuses.get(i).quote_id); } else { //Status is edited statusCall = mastodonStatusesService.updateStatus(null, dataPost.token, dataPost.statusEditId, statuses.get(i).text, attachmentIds, poll_options, poll_expire_in, poll_multiple, poll_hide_totals, in_reply_to_status, statuses.get(i).sensitive, statuses.get(i).spoilerChecked ? statuses.get(i).spoiler_text : null, statuses.get(i).visibility.toLowerCase(), language); diff --git a/app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java b/app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java index be9a5c3d..ff28d02e 100644 --- a/app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java +++ b/app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java @@ -396,6 +396,7 @@ public class StatusAdapter extends RecyclerView.Adapter boolean displayTranslate = sharedpreferences.getBoolean(context.getString(R.string.SET_DISPLAY_TRANSLATE), false); boolean displayCounters = sharedpreferences.getBoolean(context.getString(R.string.SET_DISPLAY_COUNTER_FAV_BOOST), false); boolean removeLeftMargin = sharedpreferences.getBoolean(context.getString(R.string.SET_REMOVE_LEFT_MARGIN), false); + boolean extraFeatures = sharedpreferences.getBoolean(context.getString(R.string.SET_EXTAND_EXTRA_FEATURES), false); if (removeLeftMargin) { LinearLayoutCompat.MarginLayoutParams p = (LinearLayoutCompat.MarginLayoutParams) holder.binding.spoiler.getLayoutParams(); @@ -438,6 +439,44 @@ public class StatusAdapter extends RecyclerView.Adapter String loadMediaType = sharedpreferences.getString(context.getString(R.string.SET_LOAD_MEDIA_TYPE), "ALWAYS"); + if (statusToDeal.quote != null) { + holder.binding.quotedMessage.cardviewContainer.setCardElevation(5); + holder.binding.quotedMessage.dividerCard.setVisibility(View.GONE); + holder.binding.quotedMessage.cardviewContainer.setStrokeWidth(1); + holder.binding.quotedMessage.cardviewContainer.setOnClickListener(v -> { + Intent intent = new Intent(context, ContextActivity.class); + intent.putExtra(Helper.ARG_STATUS, statusToDeal.quote); + context.startActivity(intent); + }); + holder.binding.quotedMessage.cardviewContainer.setStrokeColor(ThemeHelper.getAttColor(context, R.attr.colorPrimary)); + holder.binding.quotedMessage.statusContent.setText( + statusToDeal.quote.getSpanContent(context, + new WeakReference<>(holder.binding.quotedMessage.statusContent), null), + TextView.BufferType.SPANNABLE); + MastodonHelper.loadPPMastodon(holder.binding.quotedMessage.avatar, statusToDeal.quote.account); + if (statusToDeal.quote.account != null) { + holder.binding.quotedMessage.displayName.setText( + statusToDeal.quote.account.getSpanDisplayName(context, + new WeakReference<>(holder.binding.quotedMessage.displayName)), + TextView.BufferType.SPANNABLE); + holder.binding.quotedMessage.username.setText(String.format("@%s", statusToDeal.quote.account.acct)); + } + + if (statusToDeal.quote.spoiler_text != null && !statusToDeal.quote.spoiler_text.trim().isEmpty()) { + holder.binding.quotedMessage.spoiler.setVisibility(View.VISIBLE); + holder.binding.quotedMessage.spoiler.setText( + statusToDeal.quote.getSpanSpoiler(context, + new WeakReference<>(holder.binding.quotedMessage.spoiler), null), + TextView.BufferType.SPANNABLE); + } else { + holder.binding.quotedMessage.spoiler.setVisibility(View.GONE); + holder.binding.quotedMessage.spoiler.setText(null); + } + holder.binding.quotedMessage.cardviewContainer.setVisibility(View.VISIBLE); + } else { + holder.binding.quotedMessage.cardviewContainer.setVisibility(View.GONE); + } + if (currentAccount != null && currentAccount.api == Account.API.PLEROMA) { if (status.pleroma != null && status.pleroma.emoji_reactions != null && status.pleroma.emoji_reactions.size() > 0) { holder.binding.layoutReactions.getRoot().setVisibility(View.VISIBLE); @@ -553,9 +592,10 @@ public class StatusAdapter extends RecyclerView.Adapter int truncate_toots_size = sharedpreferences.getInt(context.getString(R.string.SET_TRUNCATE_TOOTS_SIZE), 0); - if (currentAccount != null && currentAccount.api == Account.API.PLEROMA) { + if (extraFeatures) { holder.binding.statusAddCustomEmoji.setVisibility(View.VISIBLE); holder.binding.statusEmoji.setVisibility(View.VISIBLE); + holder.binding.actionButtonQuote.setVisibility(View.VISIBLE); } holder.binding.actionButtonFavorite.pressOnTouch(false); @@ -951,6 +991,11 @@ public class StatusAdapter extends RecyclerView.Adapter holder.binding.statusAddCustomEmoji.getLayoutParams().width = (int) (normalSize * scaleIcon); holder.binding.statusAddCustomEmoji.getLayoutParams().height = (int) (normalSize * scaleIcon); holder.binding.statusAddCustomEmoji.requestLayout(); + + holder.binding.actionButtonQuote.getLayoutParams().width = (int) (normalSize * scaleIcon); + holder.binding.actionButtonQuote.getLayoutParams().height = (int) (normalSize * scaleIcon); + holder.binding.actionButtonQuote.requestLayout(); + holder.binding.statusEmoji.getLayoutParams().width = (int) (normalSize * scaleIcon); holder.binding.statusEmoji.getLayoutParams().height = (int) (normalSize * scaleIcon); holder.binding.actionButtonMore.getLayoutParams().width = (int) (normalSize * scaleIcon); @@ -1903,6 +1948,11 @@ public class StatusAdapter extends RecyclerView.Adapter CrossActionHelper.doCrossAction(context, CrossActionHelper.TypeOfCrossAction.REPLY_ACTION, null, statusToDeal); return true; }); + holder.binding.actionButtonQuote.setOnClickListener(v -> { + Intent intent = new Intent(context, ComposeActivity.class); + intent.putExtra(Helper.ARG_QUOTED_MESSAGE, statusToDeal); + context.startActivity(intent); + }); holder.binding.actionButtonReply.setOnClickListener(v -> { if (remote) { Toasty.info(context, context.getString(R.string.retrieve_remote_status), Toasty.LENGTH_SHORT).show(); @@ -2286,6 +2336,7 @@ public class StatusAdapter extends RecyclerView.Adapter if (theme_icons_color != -1) { Helper.changeDrawableColor(context, holder.binding.actionButtonReply, theme_icons_color); Helper.changeDrawableColor(context, holder.binding.statusAddCustomEmoji, theme_icons_color); + Helper.changeDrawableColor(context, holder.binding.actionButtonQuote, theme_icons_color); Helper.changeDrawableColor(context, holder.binding.statusEmoji, theme_icons_color); Helper.changeDrawableColor(context, holder.binding.actionButtonMore, theme_icons_color); Helper.changeDrawableColor(context, R.drawable.ic_round_star_24, theme_icons_color); diff --git a/app/src/main/java/app/fedilab/android/viewmodel/mastodon/StatusesVM.java b/app/src/main/java/app/fedilab/android/viewmodel/mastodon/StatusesVM.java index 82628377..ebae3e67 100644 --- a/app/src/main/java/app/fedilab/android/viewmodel/mastodon/StatusesVM.java +++ b/app/src/main/java/app/fedilab/android/viewmodel/mastodon/StatusesVM.java @@ -186,12 +186,13 @@ public class StatusesVM extends AndroidViewModel { Boolean sensitive, String spoiler_text, String visibility, - String language) { + String language, + String quote_id) { MastodonStatusesService mastodonStatusesService = init(instance); statusMutableLiveData = new MutableLiveData<>(); new Thread(() -> { Call statusCall = mastodonStatusesService.createStatus(idempotency_Key, token, text, media_ids, poll_options, poll_expire_in, - poll_multiple, poll_hide_totals, in_reply_to_id, sensitive, spoiler_text, visibility, language); + poll_multiple, poll_hide_totals, in_reply_to_id, sensitive, spoiler_text, visibility, language, quote_id); Status status = null; if (statusCall != null) { try { diff --git a/app/src/main/res/drawable/ic_baseline_format_quote_24.xml b/app/src/main/res/drawable/ic_baseline_format_quote_24.xml new file mode 100644 index 00000000..3eb67528 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_format_quote_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/drawer_status.xml b/app/src/main/res/layout/drawer_status.xml index a265701a..7dcc0a61 100644 --- a/app/src/main/res/layout/drawer_status.xml +++ b/app/src/main/res/layout/drawer_status.xml @@ -394,6 +394,12 @@ + + + + SET_NOTIF_VALIDATION_FAV SET_DISPLAY_COUNTER_FAV_BOOST SET_REMOVE_LEFT_MARGIN + SET_EXTAND_EXTRA_FEATURES SET_INNER_MARKER SET_NOTIF_SILENT @@ -2147,4 +2148,6 @@ Translator API key Version Translator version + Extra features + By enabling that option the app will display extra features. This feature is done for social softwares like Pleroma, Akkoma or Glitch Social \ No newline at end of file diff --git a/app/src/main/res/xml/pref_interface.xml b/app/src/main/res/xml/pref_interface.xml index f00bf82e..4097c3a8 100644 --- a/app/src/main/res/xml/pref_interface.xml +++ b/app/src/main/res/xml/pref_interface.xml @@ -28,6 +28,15 @@ app:summary="@string/set_remove_left_margin" app:title="@string/set_remove_left_margin_title" /> + + +