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