Merge branch 'develop' into m_quotes

This commit is contained in:
Thomas 2025-08-24 10:33:13 +02:00
commit 335fbdf983
5 changed files with 144 additions and 82 deletions

View file

@ -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;
@ -638,8 +639,8 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
}
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);
@ -1113,79 +1114,103 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
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<RecyclerView.ViewHolder>
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();

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_reblog"
android:icon="@drawable/ic_round_repeat_24"
android:title="@string/action_reblog"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_quote"
android:icon="@drawable/ic_baseline_format_quote_24"
android:title="@string/action_quote"
app:showAsAction="ifRoom" />
</menu>

View file

@ -1126,4 +1126,8 @@
<string name="about_fediverse">フェディバース:</string>
<string name="about_website">ウェブサイト:</string>
<string name="about_donate">寄付:</string>
<string name="default_who_can_quote">デフォルトの見積可能者を選択</string>
<string name="who_can_quote">見積可能者</string>
<string name="no_one">誰も</string>
<string name="anyone">誰か</string>
</resources>

View file

@ -1137,4 +1137,5 @@
<string name="who_can_quote">Хто може цитувати</string>
<string name="no_one">Ніхто</string>
<string name="anyone">Будь-хто</string>
<string name="default_who_can_quote">Вибір за замовчуванням для тих, хто може котирувати</string>
</resources>

View file

@ -0,0 +1,26 @@
追加:
- トップ・バーのタブのコンテンツ説明
- タイムライン中の投稿のメディアの感度切替を容易にするアクション
- メディアビューワー中の翻訳、ダウンロード、共有を容易にするアクション
- フォーカスされたステータスに言語インジケーター
- "言語の変更"選択肢のペルシャ語
- 新たなアプリのロゴ
変更:
- プロフィール写真読込中はプレースホルダーを表示する
- 下部ナビゲーションタブのタイトルを刷新
- 翻訳コンテンツの利用しやすさを改善
- "UTMパラメータの削除"で使用するトラッキングパラメータの一覧を更新
- "UTM"の代わりに"トラッキング"を利用
- タイムラインページの管理の利用しやすさを改善
- メディアの表示/非表示ボタンをより大きくした
- ページに関する更新
修正:
- "下部ハッシュタグをハイライト"が有効時にタグ中のBIOSが消失する
- "代替フロントエンドを使う"でミディアム・リンクが壊れてしまう
- 公開ボタンを複数回タップすると、ステータスも複数回公開される
- スワイプ時Altテキストポップアップのサイズが変更されない
- 明るいテーマでビデオコントロールが利用できない
- RTLモードの会話ページで、プロフ画像がタイトル左側に表示される
- 幾つかのクラッシュ