diff --git a/.gitignore b/.gitignore
index 8db2f09ab..f230a7d4c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,4 +16,4 @@ obj
/captures
/local.properties
-libc++_shared.so
\ No newline at end of file
+libc++_shared.so
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..53fce3403 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;
@@ -79,12 +108,18 @@ public TopBarView (@NonNull Context context) {
setLayoutParams(FrameLayoutFix.newParams(ViewGroup.LayoutParams.MATCH_PARENT, Screen.dp(36f)));
ViewSupport.setThemedBackground(this, ColorId.filling, null);
+ actionsContainer = new LinearLayout(context);
+ actionsContainer.setOrientation(LinearLayout.VERTICAL);
+ actionsContainer.setLayoutParams(FrameLayoutFix.newParams(ViewGroup.LayoutParams.MATCH_PARENT, Screen.dp(40f), 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);
+ 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,59 @@ 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.TOP))));
+
+ LinearLayout noticeItem = new LinearLayout(getContext());
+ noticeItem.setOrientation(LinearLayout.HORIZONTAL);
+ noticeItem.setGravity(Lang.gravity());
+ noticeItem.setBackgroundResource(R.drawable.bg_btn_header);
+ noticeItem.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT, 2f));
+ /* Rudimentary debugging
+ android.util.Log.d("TopBarView", String.format("Width: %d, Height: %d", ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT));
+ android.util.Log.d("TopBarView", String.format("Width: %d, Height: %d", noticeItem.getWidth(), noticeItem.getHeight()));
+ */
+
+ 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);
}
- 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.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);
+ setLayoutParams(FrameLayoutFix.newParams(ViewGroup.LayoutParams.MATCH_PARENT, Screen.dp(50f)));
+
+ 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 47cd49536..f975d57ec 100644
--- a/app/src/main/java/org/thunderdog/challegram/ui/MessagesController.java
+++ b/app/src/main/java/org/thunderdog/challegram/ui/MessagesController.java
@@ -782,7 +782,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()
@@ -8020,13 +8020,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) {
@@ -8046,7 +8046,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)
.setHeaderItem(new ListItem(ListItem.TYPE_INFO, 0, 0, Lang.getStringBold(R.string.ReportChatSpam, chat.title), false))
.setRawItems(getChatUserId() != 0 ? new ListItem[] {
@@ -8143,6 +8143,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));
@@ -8152,6 +8160,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) {
@@ -8210,7 +8226,7 @@ public boolean onSenderPick (ContactsController context, View view, TdApi.Messag
}
case TdApi.ChatActionBarJoinRequest.CONSTRUCTOR: {
TdApi.ChatActionBarJoinRequest joinRequest = (TdApi.ChatActionBarJoinRequest) actionBar;
- // TODO
+ items.add(new TopBarView.Item(Strings.replaceBoldTokens(Lang.getString(R.string.JoinRequestChannelAdminNotice, 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 df11eef24..3bf430299 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -5477,4 +5477,7 @@
Hold to access more options
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 channel you requested to join