From 6fbec43c0f63883824cf30ee387fb6a54ad447dd Mon Sep 17 00:00:00 2001 From: Liner Seven Date: Sat, 23 Aug 2025 16:02:02 +0200 Subject: [PATCH 1/5] Translated using Weblate (Japanese) Currently translated at 100.0% (1259 of 1259 strings) Co-authored-by: Liner Seven Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/ja/ Translation: Fedilab/Strings --- app/src/main/res/values-ja/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index a4aefd9c..ff8cd338 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -1126,4 +1126,8 @@ フェディバース: ウェブサイト: 寄付: + デフォルトの見積可能者を選択 + 見積可能者 + 誰も + 誰か From 9dd3e62be0f798671fbee8a2f7cc25e0626bab43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D0=BA=D1=81=D0=B8=D0=BC=20=D0=93=D0=BE=D1=80?= =?UTF-8?q?=D0=BF=D0=B8=D0=BD=D1=96=D1=87?= Date: Sat, 23 Aug 2025 16:02:06 +0200 Subject: [PATCH 2/5] Translated using Weblate (Ukrainian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (1259 of 1259 strings) Co-authored-by: Максим Горпиніч Translate-URL: https://hosted.weblate.org/projects/fedilab/strings/uk/ Translation: Fedilab/Strings --- app/src/main/res/values-uk/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index a97c02b1..15ea875b 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -1137,4 +1137,5 @@ Хто може цитувати Ніхто Будь-хто + Вибір за замовчуванням для тих, хто може котирувати From 8c1d48be05aab666a3685ab26c964c71400950b9 Mon Sep 17 00:00:00 2001 From: Liner Seven Date: Sat, 23 Aug 2025 16:02:13 +0200 Subject: [PATCH 3/5] Translated using Weblate (Japanese) Currently translated at 100.0% (40 of 40 strings) Co-authored-by: Liner Seven Translate-URL: https://hosted.weblate.org/projects/fedilab/description/ja/ Translation: Fedilab/description --- .../metadata/android/ja/changelogs/538.txt | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/fdroid/fastlane/metadata/android/ja/changelogs/538.txt diff --git a/src/fdroid/fastlane/metadata/android/ja/changelogs/538.txt b/src/fdroid/fastlane/metadata/android/ja/changelogs/538.txt new file mode 100644 index 00000000..df343077 --- /dev/null +++ b/src/fdroid/fastlane/metadata/android/ja/changelogs/538.txt @@ -0,0 +1,26 @@ +追加: +- トップ・バーのタブのコンテンツ説明 +- タイムライン中の投稿のメディアの感度切替を容易にするアクション +- メディアビューワー中の翻訳、ダウンロード、共有を容易にするアクション +- フォーカスされたステータスに言語インジケーター +- "言語の変更"選択肢のペルシャ語 +- 新たなアプリのロゴ + +変更: +- プロフィール写真読込中はプレースホルダーを表示する +- 下部ナビゲーションタブのタイトルを刷新 +- 翻訳コンテンツの利用しやすさを改善 +- "UTMパラメータの削除"で使用するトラッキングパラメータの一覧を更新 +- "UTM"の代わりに"トラッキング"を利用 +- タイムラインページの管理の利用しやすさを改善 +- メディアの表示/非表示ボタンをより大きくした +- ページに関する更新 + +修正: +- "下部ハッシュタグをハイライト"が有効時にタグ中のBIOSが消失する +- "代替フロントエンドを使う"でミディアム・リンクが壊れてしまう +- 公開ボタンを複数回タップすると、ステータスも複数回公開される +- スワイプ時Altテキストポップアップのサイズが変更されない +- 明るいテーマでビデオコントロールが利用できない +- RTLモードの会話ページで、プロフ画像がタイトル左側に表示される +- 幾つかのクラッシュ From f3e8090c5aea59562ea82e1dcb89958f5547f0b8 Mon Sep 17 00:00:00 2001 From: 0xd9a <0xd9a@noreply.codeberg.org> Date: Sat, 23 Aug 2025 22:02:04 +0530 Subject: [PATCH 4/5] Show emoji buttons only in focused status --- .../app/fedilab/android/mastodon/ui/drawer/StatusAdapter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 feff53b7..94e66204 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 @@ -638,8 +638,8 @@ public class StatusAdapter extends RecyclerView.Adapter } if (extraFeatures && displayReactions) { - holder.binding.statusAddCustomEmoji.setVisibility(View.VISIBLE); - holder.binding.statusEmoji.setVisibility(View.VISIBLE); + holder.binding.statusAddCustomEmoji.setVisibility(status.isFocused ? View.VISIBLE : View.GONE); + holder.binding.statusEmoji.setVisibility(status.isFocused ? View.VISIBLE : View.GONE); if (status.pleroma != null && status.pleroma.emoji_reactions != null && !status.pleroma.emoji_reactions.isEmpty()) { holder.binding.layoutReactions.getRoot().setVisibility(View.VISIBLE); ReactionAdapter reactionAdapter = new ReactionAdapter(status.id, status.pleroma.emoji_reactions, true); From 4301c603071768016f6dc4651903bc50cfe6a5cb Mon Sep 17 00:00:00 2001 From: 0xd9a <0xd9a@noreply.codeberg.org> Date: Sun, 24 Aug 2025 01:27:58 +0530 Subject: [PATCH 5/5] Add popup menu for boost, quote actions in status --- .../mastodon/ui/drawer/StatusAdapter.java | 174 ++++++++++-------- .../mastodon/menu/menu_boost_or_quote.xml | 17 ++ 2 files changed, 111 insertions(+), 80 deletions(-) create mode 100644 app/src/main/res/menus/mastodon/menu/menu_boost_or_quote.xml 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 94e66204..cfccc84e 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 @@ -62,6 +62,7 @@ import android.text.SpannableString; import android.text.TextUtils; import android.util.TypedValue; import android.view.LayoutInflater; +import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; @@ -1113,79 +1114,103 @@ public class StatusAdapter extends RecyclerView.Adapter return true; }); holder.binding.actionButtonBoost.setOnClickListener(v -> { - boolean needToWarnForMissingDescription = false; - if (warnNoMedia && statusToDeal.media_attachments != null && statusToDeal.media_attachments.size() > 0) { - for (Attachment attachment : statusToDeal.media_attachments) { - if (attachment.description == null || attachment.description.trim().length() == 0) { - needToWarnForMissingDescription = true; - break; - } - } - } - if (confirmBoost || needToWarnForMissingDescription) { - AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(context); - - if (statusToDeal.reblogged) { - alt_bld.setMessage(context.getString(R.string.reblog_remove)); - } else { - if (!needToWarnForMissingDescription) { - alt_bld.setMessage(context.getString(R.string.reblog_add)); - } else { - alt_bld.setMessage(context.getString(R.string.reblog_missing_description)); - } - } - alt_bld.setPositiveButton(R.string.yes, (dialog, id) -> { - if (remote) { - Toasty.info(context, context.getString(R.string.retrieve_remote_status), Toasty.LENGTH_SHORT).show(); - searchVM.search(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.uri, null, "statuses", false, true, false, 0, null, null, 1) - .observe((LifecycleOwner) context, results -> { - if (results != null && results.statuses != null && results.statuses.size() > 0) { - Status fetchedStatus = results.statuses.get(0); - statusesVM.reblog(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, fetchedStatus.id, null) - .observe((LifecycleOwner) context, _status -> manageAction(context, adapter, holder, CrossActionHelper.TypeOfCrossAction.REBLOG_ACTION, statusToDeal, _status, true)); - } else { - Toasty.info(context, context.getString(R.string.toast_error_search), Toasty.LENGTH_SHORT).show(); - } - }); - } else { - if (statusToDeal.reblogged) { - statusesVM.unReblog(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id) - .observe((LifecycleOwner) context, _status -> manageAction(context, adapter, holder, CrossActionHelper.TypeOfCrossAction.UNREBLOG_ACTION, statusToDeal, _status, false)); - } else { - ((SparkButton) v).playAnimation(); - statusesVM.reblog(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, null) - .observe((LifecycleOwner) context, _status -> manageAction(context, adapter, holder, CrossActionHelper.TypeOfCrossAction.REBLOG_ACTION, statusToDeal, _status, false)); - } - } - dialog.dismiss(); - }); - alt_bld.setNegativeButton(R.string.cancel, (dialog, id) -> dialog.dismiss()); - AlertDialog alert = alt_bld.create(); - alert.show(); - } else { - if (remote) { - Toasty.info(context, context.getString(R.string.retrieve_remote_status), Toasty.LENGTH_SHORT).show(); - searchVM.search(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.uri, null, "statuses", false, true, false, 0, null, null, 1) - .observe((LifecycleOwner) context, results -> { - if (results != null && results.statuses != null && results.statuses.size() > 0) { - Status fetchedStatus = results.statuses.get(0); - statusesVM.reblog(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, fetchedStatus.id, null) - .observe((LifecycleOwner) context, _status -> manageAction(context, adapter, holder, CrossActionHelper.TypeOfCrossAction.REBLOG_ACTION, statusToDeal, _status, true)); - } else { - Toasty.info(context, context.getString(R.string.toast_error_search), Toasty.LENGTH_SHORT).show(); + PopupMenu popupMenu = new PopupMenu(context, v); + popupMenu.getMenuInflater().inflate(R.menu.menu_boost_or_quote, popupMenu.getMenu()); + popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + int itemId = item.getItemId(); + if (itemId == R.id.action_reblog) { + boolean needToWarnForMissingDescription = false; + if (warnNoMedia && statusToDeal.media_attachments != null && statusToDeal.media_attachments.size() > 0) { + for (Attachment attachment : statusToDeal.media_attachments) { + if (attachment.description == null || attachment.description.trim().length() == 0) { + needToWarnForMissingDescription = true; + break; } + } + } + if (confirmBoost || needToWarnForMissingDescription) { + AlertDialog.Builder alt_bld = new MaterialAlertDialogBuilder(context); + + if (statusToDeal.reblogged) { + alt_bld.setMessage(context.getString(R.string.reblog_remove)); + } else { + if (!needToWarnForMissingDescription) { + alt_bld.setMessage(context.getString(R.string.reblog_add)); + } else { + alt_bld.setMessage(context.getString(R.string.reblog_missing_description)); + } + } + alt_bld.setPositiveButton(R.string.yes, (dialog, id) -> { + if (remote) { + Toasty.info(context, context.getString(R.string.retrieve_remote_status), Toasty.LENGTH_SHORT).show(); + searchVM.search(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.uri, null, "statuses", false, true, false, 0, null, null, 1) + .observe((LifecycleOwner) context, results -> { + if (results != null && results.statuses != null && results.statuses.size() > 0) { + Status fetchedStatus = results.statuses.get(0); + statusesVM.reblog(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, fetchedStatus.id, null) + .observe((LifecycleOwner) context, _status -> manageAction(context, adapter, holder, CrossActionHelper.TypeOfCrossAction.REBLOG_ACTION, statusToDeal, _status, true)); + } else { + Toasty.info(context, context.getString(R.string.toast_error_search), Toasty.LENGTH_SHORT).show(); + } + }); + } else { + if (statusToDeal.reblogged) { + statusesVM.unReblog(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id) + .observe((LifecycleOwner) context, _status -> manageAction(context, adapter, holder, CrossActionHelper.TypeOfCrossAction.UNREBLOG_ACTION, statusToDeal, _status, false)); + } else { + ((SparkButton) v).playAnimation(); + statusesVM.reblog(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, null) + .observe((LifecycleOwner) context, _status -> manageAction(context, adapter, holder, CrossActionHelper.TypeOfCrossAction.REBLOG_ACTION, statusToDeal, _status, false)); + } + } + dialog.dismiss(); }); - } else { - if (statusToDeal.reblogged) { - statusesVM.unReblog(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id) - .observe((LifecycleOwner) context, _status -> manageAction(context, adapter, holder, CrossActionHelper.TypeOfCrossAction.UNREBLOG_ACTION, statusToDeal, _status, false)); - } else { - ((SparkButton) v).playAnimation(); - statusesVM.reblog(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, null) - .observe((LifecycleOwner) context, _status -> manageAction(context, adapter, holder, CrossActionHelper.TypeOfCrossAction.REBLOG_ACTION, statusToDeal, _status, false)); + alt_bld.setNegativeButton(R.string.cancel, (dialog, id) -> dialog.dismiss()); + AlertDialog alert = alt_bld.create(); + alert.show(); + } else { + if (remote) { + Toasty.info(context, context.getString(R.string.retrieve_remote_status), Toasty.LENGTH_SHORT).show(); + searchVM.search(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.uri, null, "statuses", false, true, false, 0, null, null, 1) + .observe((LifecycleOwner) context, results -> { + if (results != null && results.statuses != null && results.statuses.size() > 0) { + Status fetchedStatus = results.statuses.get(0); + statusesVM.reblog(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, fetchedStatus.id, null) + .observe((LifecycleOwner) context, _status -> manageAction(context, adapter, holder, CrossActionHelper.TypeOfCrossAction.REBLOG_ACTION, statusToDeal, _status, true)); + } else { + Toasty.info(context, context.getString(R.string.toast_error_search), Toasty.LENGTH_SHORT).show(); + } + }); + } else { + if (statusToDeal.reblogged) { + statusesVM.unReblog(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id) + .observe((LifecycleOwner) context, _status -> manageAction(context, adapter, holder, CrossActionHelper.TypeOfCrossAction.UNREBLOG_ACTION, statusToDeal, _status, false)); + } else { + ((SparkButton) v).playAnimation(); + statusesVM.reblog(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, null) + .observe((LifecycleOwner) context, _status -> manageAction(context, adapter, holder, CrossActionHelper.TypeOfCrossAction.REBLOG_ACTION, statusToDeal, _status, false)); + } + } + } + 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; } - } + }); + popupMenu.show(); }); holder.binding.actionButtonBoost.setChecked(statusToDeal.reblogged); //---> FAVOURITE/UNFAVOURITE @@ -2350,17 +2375,6 @@ 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); - 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); - }); - }); holder.binding.actionButtonReplyContainer.setOnClickListener(v -> { if (remote) { Toasty.info(context, context.getString(R.string.retrieve_remote_status), Toasty.LENGTH_SHORT).show(); diff --git a/app/src/main/res/menus/mastodon/menu/menu_boost_or_quote.xml b/app/src/main/res/menus/mastodon/menu/menu_boost_or_quote.xml new file mode 100644 index 00000000..a9e1b0c5 --- /dev/null +++ b/app/src/main/res/menus/mastodon/menu/menu_boost_or_quote.xml @@ -0,0 +1,17 @@ + + + + + + + +