diff --git a/app/src/main/java/org/thunderdog/challegram/component/chat/TopBarView.java b/app/src/main/java/org/thunderdog/challegram/component/chat/TopBarView.java
index bc776ebf8..1ddc62c16 100644
--- a/app/src/main/java/org/thunderdog/challegram/component/chat/TopBarView.java
+++ b/app/src/main/java/org/thunderdog/challegram/component/chat/TopBarView.java
@@ -12,6 +12,7 @@
*/
package org.thunderdog.challegram.component.chat;
+import android.annotation.SuppressLint;
import android.content.Context;
import android.text.TextUtils;
import android.view.Gravity;
@@ -24,6 +25,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.appcompat.widget.AppCompatImageView;
import org.thunderdog.challegram.R;
import org.thunderdog.challegram.core.Lang;
@@ -38,7 +40,8 @@
public class TopBarView extends FrameLayoutFix {
private final ImageView topDismissButton;
- private final LinearLayout actionsList;
+ private final LinearLayout actionsContainer;
+ private LinearLayout actionsList;
private boolean canDismiss;
@@ -49,17 +52,43 @@ public interface DismissListener {
public static class Item {
final int id;
final int stringRes;
+ final CharSequence noticeRes;
+ final int iconResId;
final View.OnClickListener onClickListener;
+ final boolean showDismissRight;
boolean isNegative;
boolean noDismiss;
- public Item (int id, int stringRes, View.OnClickListener onClickListener) {
+ public Item (int id, int stringRes, CharSequence noticeRes, int iconResId, boolean showDismissRight, View.OnClickListener onClickListener) {
this.id = id;
this.stringRes = stringRes;
+ this.noticeRes = noticeRes;
+ this.iconResId = iconResId;
+ this.showDismissRight = showDismissRight;
this.onClickListener = onClickListener;
}
+ public Item (int id, int stringRes, boolean showDismissRight, int iconResId, View.OnClickListener onClickListener) {
+ this(id, stringRes, null, iconResId, showDismissRight, onClickListener);
+ }
+
+ public Item (int id, int stringRes, boolean showDismissRight, View.OnClickListener onClickListener) {
+ this(id, stringRes, null, 0, showDismissRight, onClickListener);
+ }
+
+ public Item (int id, int stringRes, View.OnClickListener onClickListener) {
+ this(id, stringRes, null, 0, false, onClickListener);
+ }
+
+ public Item (CharSequence noticeRes, boolean showDismissRight) {
+ this(0, 0, noticeRes, 0, showDismissRight, null);
+ }
+
+ public Item (CharSequence noticeRes) {
+ this(0, 0, noticeRes, 0, false, null);
+ }
+
public Item setIsNegative () {
this.isNegative = true;
return this;
@@ -76,15 +105,21 @@ public Item setNoDismiss () {
public TopBarView (@NonNull Context context) {
super(context);
- setLayoutParams(FrameLayoutFix.newParams(ViewGroup.LayoutParams.MATCH_PARENT, Screen.dp(36f)));
+ setLayoutParams(FrameLayoutFix.newParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
ViewSupport.setThemedBackground(this, ColorId.filling, null);
+ actionsContainer = new LinearLayout(context);
+ actionsContainer.setOrientation(LinearLayout.VERTICAL);
+ actionsContainer.setLayoutParams(FrameLayoutFix.newParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, Lang.gravity() | Gravity.TOP));
+ addView(actionsContainer);
+
actionsList = new LinearLayout(context);
actionsList.setOrientation(LinearLayout.HORIZONTAL);
- actionsList.setLayoutParams(FrameLayoutFix.newParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, Lang.gravity() | Gravity.TOP));
- addView(actionsList);
+ actionsList.setLayoutParams(FrameLayoutFix.newParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, Lang.gravity() | Gravity.TOP));
+ actionsContainer.addView(actionsList);
- topDismissButton = new ImageView(context) {
+ topDismissButton = new AppCompatImageView(context) {
+ @SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent (MotionEvent event) {
return Views.isValid(this) && super.onTouchEvent(event);
@@ -98,7 +133,6 @@ public boolean onTouchEvent (MotionEvent event) {
topDismissButton.setScaleType(ImageView.ScaleType.CENTER);
topDismissButton.setColorFilter(Theme.iconColor());
topDismissButton.setImageResource(R.drawable.baseline_close_18);
- topDismissButton.setLayoutParams(FrameLayoutFix.newParams(Screen.dp(40f), ViewGroup.LayoutParams.MATCH_PARENT, Lang.gravity() | Gravity.TOP));
topDismissButton.setBackgroundResource(R.drawable.bg_btn_header);
Views.setClickable(topDismissButton);
topDismissButton.setVisibility(View.INVISIBLE);
@@ -127,6 +161,7 @@ public void setCanDismiss (boolean canDismiss) {
}
public void setItems (Item... items) {
+ actionsList = (LinearLayout) actionsContainer.getChildAt(0);
for (int i = 0; i < actionsList.getChildCount(); i++) {
View view = actionsList.getChildAt(i);
if (view != null && themeProvider != null) {
@@ -145,19 +180,63 @@ public void setItems (Item... items) {
canDismiss = true;
}
int textColorId = item.isNegative ? ColorId.textNegative : ColorId.textNeutral;
- TextView button = Views.newTextView(getContext(), 15f, Theme.getColor(textColorId), Gravity.CENTER, Views.TEXT_FLAG_BOLD | Views.TEXT_FLAG_HORIZONTAL_PADDING);
- button.setId(item.id);
- if (themeProvider != null) {
- themeProvider.addThemeTextColorListener(button, textColorId);
+
+ LinearLayout buttonLayout = new LinearLayout(getContext());
+ buttonLayout.setOrientation(LinearLayout.HORIZONTAL);
+ buttonLayout.setGravity(Gravity.CENTER);
+ buttonLayout.setBackgroundResource(R.drawable.bg_btn_header);
+ buttonLayout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT, 2f));
+ Views.setClickable(buttonLayout);
+
+ topDismissButton.setLayoutParams(FrameLayoutFix.newParams(Screen.dp(40f), ViewGroup.LayoutParams.MATCH_PARENT, (item.showDismissRight ? (Gravity.END | Gravity.CENTER_VERTICAL) : (Lang.gravity() | Gravity.CENTER_VERTICAL))));
+
+ LinearLayout noticeItem = new LinearLayout(getContext());
+ noticeItem.setOrientation(LinearLayout.HORIZONTAL);
+ noticeItem.setGravity(Gravity.CENTER);
+ noticeItem.setBackgroundColor(0x00000000);
+ noticeItem.setPadding(0, 0, 0, 0);
+ noticeItem.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, 2f));
+
+ if (item.iconResId != 0) {
+ ImageView iconView = new ImageView(getContext());
+ iconView.setImageResource(item.iconResId);
+ iconView.setColorFilter(Theme.getColor(textColorId));
+ iconView.setLayoutParams(new LinearLayout.LayoutParams(Screen.dp(24f), Screen.dp(24f)));
+ buttonLayout.addView(iconView);
+ LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) iconView.getLayoutParams();
+ layoutParams.rightMargin = Screen.dp(8);
+ iconView.setLayoutParams(layoutParams);
}
- button.setEllipsize(TextUtils.TruncateAt.END);
- button.setSingleLine(true);
- button.setBackgroundResource(R.drawable.bg_btn_header);
- button.setOnClickListener(item.onClickListener);
- Views.setMediumText(button, Lang.getString(item.stringRes).toUpperCase());
- Views.setClickable(button);
- button.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT, 2f));
- actionsList.addView(button);
+
+ if (item.stringRes != 0) {
+ TextView buttonText = Views.newTextView(getContext(), 15f, Theme.getColor(textColorId), Gravity.CENTER, Views.TEXT_FLAG_BOLD | Views.TEXT_FLAG_HORIZONTAL_PADDING);
+ buttonText.setId(item.id);
+
+ if (themeProvider != null) {
+ themeProvider.addThemeTextColorListener(buttonText, textColorId);
+ }
+
+ buttonText.setEllipsize(TextUtils.TruncateAt.END);
+ buttonText.setSingleLine(true);
+ buttonText.setPadding(Screen.dp(8), 0, Screen.dp(8), 0);
+ buttonText.setText(Lang.getString(item.stringRes).toUpperCase());
+ buttonText.setOnClickListener(item.onClickListener);
+ buttonLayout.addView(buttonText);
+ actionsList.addView(buttonLayout);
+ }
+
+ if (item.noticeRes != null) {
+ var noticeText = Views.newTextView(getContext(), 15f, Theme.getColor(ColorId.textPlaceholder), ViewGroup.MEASURED_HEIGHT_STATE_SHIFT, Views.TEXT_FLAG_HORIZONTAL_PADDING);
+ noticeText.setText(item.noticeRes);
+ noticeText.setGravity(Gravity.START);
+ noticeText.setPadding(Screen.dp(16), Screen.dp(8), Screen.dp(26), Screen.dp(8));
+ noticeText.setSingleLine(false);
+ noticeText.setEllipsize(null);
+ setLayoutParams(FrameLayoutFix.newParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+ noticeItem.addView(noticeText);
+ actionsList.addView(noticeItem);
+ }
+
}
if (items.length > 1) {
View offsetView = new View(getContext());
diff --git a/app/src/main/java/org/thunderdog/challegram/ui/MessagesController.java b/app/src/main/java/org/thunderdog/challegram/ui/MessagesController.java
index 0c846cddf..e4671be95 100644
--- a/app/src/main/java/org/thunderdog/challegram/ui/MessagesController.java
+++ b/app/src/main/java/org/thunderdog/challegram/ui/MessagesController.java
@@ -852,7 +852,7 @@ protected void onDraw (Canvas c) {
liveLocationView.setLayoutParams(FrameLayoutFix.newParams(ViewGroup.LayoutParams.MATCH_PARENT, liveLocationHeight));
addThemeInvalidateListener(liveLocationView);
- int actionBarHeight = Screen.dp(36f);
+ int actionBarHeight = Screen.dp(46f);
actionView = new TopBarView(context);
actionView.setDismissListener(barView ->
dismissActionBar()
@@ -942,7 +942,7 @@ public void onCompletelyHidden () {
pinnedMessagesItem,
requestsItem = new CollapseListView.ViewItem(requestsView, requestsViewHeight),
liveLocationItem = new CollapseListView.ViewItem(liveLocationView, liveLocationHeight),
- actionItem = new CollapseListView.ViewItem(actionView, actionBarHeight),
+ actionItem = new CollapseListView.ViewItem(actionView, ViewGroup.LayoutParams.WRAP_CONTENT),
toastAlertItem
}, this);
@@ -8178,13 +8178,13 @@ private boolean needActionBar () {
}
private TopBarView.Item newAddContactItem (long chatId) {
- return new TopBarView.Item(R.id.btn_addContact, R.string.AddContact, v -> {
+ return new TopBarView.Item(R.id.btn_addContact, R.string.AddContact, true, R.drawable.baseline_person_add_24, v -> {
tdlib.ui().addContact(this, tdlib.chatUser(chatId));
});
}
private TopBarView.Item newUnarchiveItem (long chatId) {
- return new TopBarView.Item(R.id.btn_unarchiveChat, R.string.UnarchiveUnmute, v -> {
+ return new TopBarView.Item(R.id.btn_unarchiveChat, R.string.UnarchiveUnmute, true, R.drawable.baseline_unarchive_24, v -> {
tdlib.client().send(new TdApi.AddChatToList(chatId, new TdApi.ChatListMain()), tdlib.okHandler());
TdApi.ChatNotificationSettings settings = tdlib.chatSettings(chatId);
if (settings != null) {
@@ -8204,7 +8204,7 @@ private TopBarView.Item newUnarchiveItem (long chatId) {
}
private TopBarView.Item newReportItem (long chatId, boolean isBlock) {
- return new TopBarView.Item(R.id.btn_reportChat, isBlock ? R.string.BlockContact : R.string.ReportSpam, v -> {
+ return new TopBarView.Item(R.id.btn_reportChat, isBlock ? R.string.BlockContact : R.string.ReportSpam, true, isBlock ? R.drawable.baseline_block_24 : R.drawable.baseline_report_24, v -> {
showSettings(new SettingsWrapBuilder(R.id.btn_reportSpam)
.addHeaderItem(new ListItem(ListItem.TYPE_INFO, 0, 0, Lang.getStringBold(R.string.ReportChatSpam, chat.title), false))
.setRawItems(getChatUserId() != 0 ? new ListItem[] {
@@ -8278,6 +8278,14 @@ private void checkActionBar () {
case TdApi.ChatActionBarReportSpam.CONSTRUCTOR: {
TdApi.ChatActionBarReportSpam reportSpam = (TdApi.ChatActionBarReportSpam) actionBar;
+ /*
+ TODO: Add anti-scam notice for custom emojis
+ var customEmoji = tdlib().cache().user(tdlib.chatUserId(getChatId()));
+ android.util.Log.e("customEmoji", String.format("customEmoji: %s", customEmoji));
+ if (customEmoji != null && customEmoji.emojiStatus != null) {
+ items.add(new TopBarView.Item("Have a custom emoji", true));
+ }
+ */
items.add(newReportItem(chatId, false));
if (reportSpam.canUnarchive) {
items.add(newUnarchiveItem(chatId));
@@ -8287,6 +8295,14 @@ private void checkActionBar () {
case TdApi.ChatActionBarReportAddBlock.CONSTRUCTOR: {
TdApi.ChatActionBarReportAddBlock reportAddBlock = (TdApi.ChatActionBarReportAddBlock) actionBar;
+ /*
+ TODO: Add anti-scam notice for custom emojis
+ var customEmoji = tdlib().cache().user(tdlib.chatUserId(getChatId()));
+ android.util.Log.e("customEmoji", String.format("customEmoji: %s", customEmoji));
+ if (customEmoji != null && customEmoji.emojiStatus != null) {
+ items.add(new TopBarView.Item("Have a custom emoji", true));
+ }
+ */
items.add(newReportItem(chatId, true));
items.add(newAddContactItem(chatId));
if (reportAddBlock.canUnarchive) {
@@ -8345,7 +8361,8 @@ public boolean onSenderPick (ContactsController context, View view, TdApi.Messag
}
case TdApi.ChatActionBarJoinRequest.CONSTRUCTOR: {
TdApi.ChatActionBarJoinRequest joinRequest = (TdApi.ChatActionBarJoinRequest) actionBar;
- // TODO
+ int noticeResId = joinRequest.isChannel ? R.string.JoinRequestChannelAdminNotice : R.string.JoinRequestGroupAdminNotice;
+ items.add(new TopBarView.Item(Strings.replaceBoldTokens(Lang.getString(noticeResId, tdlib.cache().userFirstName(tdlib.chatUserId(getChatId())), joinRequest.title)), true));
break;
}
default: {
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 17da6007c..70a99eaac 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -5623,6 +5623,9 @@
Hold and swipe horizontally for precise adjustment
%1$s.\n%2$s.
+ **%1$s** is an admin of **%2$s**, a channel you requested to join
+ **%1$s** is an admin of **%2$s**, a group you requested to join
+
deactivated bot
Report Ad