diff --git a/TMessagesProj/src/main/java/org/telegram/tgnet/ConnectionsManager.java b/TMessagesProj/src/main/java/org/telegram/tgnet/ConnectionsManager.java index 51f2494acc..9e687590cd 100644 --- a/TMessagesProj/src/main/java/org/telegram/tgnet/ConnectionsManager.java +++ b/TMessagesProj/src/main/java/org/telegram/tgnet/ConnectionsManager.java @@ -292,6 +292,10 @@ public int sendRequest(final TLObject object, final RequestDelegate onComplete, return sendRequest(object, onComplete, null, onQuickAck, onWriteToSocket, flags, datacenterId, connetionType, immediate); } + public int sendRequestSync(final TLObject object, final RequestDelegate onComplete) { + return sendRequestSync(object, onComplete, null, null, 0, ConnectionsManager.DEFAULT_DATACENTER_ID, ConnectionsManager.ConnectionTypeGeneric, true); + } + public int sendRequestSync(final TLObject object, final RequestDelegate onComplete, final QuickAckDelegate onQuickAck, final WriteToSocketDelegate onWriteToSocket, final int flags, final int datacenterId, final int connetionType, final boolean immediate) { final int requestToken = lastRequestToken.getAndIncrement(); sendRequestInternal(object, onComplete, null, onQuickAck, onWriteToSocket, flags, datacenterId, connetionType, immediate, requestToken); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatUsersActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatUsersActivity.java index 0e34d88f95..d9e78d098c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatUsersActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatUsersActivity.java @@ -69,6 +69,7 @@ import org.telegram.ui.Cells.TextCheckCell2; import org.telegram.ui.Cells.TextInfoPrivacyCell; import org.telegram.ui.Cells.TextSettingsCell; +import org.telegram.ui.Components.AlertsCreator; import org.telegram.ui.Components.BulletinFactory; import org.telegram.ui.Components.CubicBezierInterpolator; import org.telegram.ui.Components.FlickerLoadingView; @@ -153,6 +154,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente private int addNew2Row; private int removedUsersRow; private int addNewSectionRow; + private int chatCleanupSectionRow; private int restricted1SectionRow; private int participantsStartRow; private int participantsEndRow; @@ -284,6 +286,7 @@ private void updateRows() { addNew2Row = -1; hideMembersRow = -1; hideMembersInfoRow = -1; + chatCleanupSectionRow = -1; addNewSectionRow = -1; restricted1SectionRow = -1; participantsStartRow = -1; @@ -449,6 +452,9 @@ private void updateRows() { loadingUserCellRow = rowCount++; } } else if (type == TYPE_USERS) { + if (!isChannel && ChatObject.canBlockUsers(currentChat)) { + chatCleanupSectionRow = rowCount++; + } if (ChatObject.isChannel(currentChat) && ChatObject.hasAdminRights(currentChat)) { if (!ChatObject.isChannelAndNotMegaGroup(currentChat) && !needOpenSearch) { hideMembersRow = rowCount++; @@ -937,6 +943,94 @@ public void needAddBot(TLRPC.User user) { }); } return; + } else if (position == chatCleanupSectionRow) { + AlertsCreator.createInactivityPeriodPickerDialog(context, getResourceProvider(), (notify, seconds) -> { + AlertDialog alertDialog = new AlertDialog(context, AlertDialog.ALERT_TYPE_SPINNER); + alertDialog.setCanCancel(false); + alertDialog.show(); + + TLRPC.TL_channels_getParticipants req = new TLRPC.TL_channels_getParticipants(); + req.channel = getMessagesController().getInputChannel(chatId); + req.limit = 250000; // даже не спрашивай + req.filter = new TLRPC.TL_channelParticipantsRecent(); + + getConnectionsManager().sendRequest(req, ((res, err) -> { + if (res != null) { + final ArrayList usersToDie = new ArrayList<>(); + // знакомая ситуация? + AtomicInteger totalUsers = new AtomicInteger(0); + AtomicInteger processedUsers = new AtomicInteger(0); + + final TLRPC.TL_channels_channelParticipants response = (TLRPC.TL_channels_channelParticipants) res; + for (TLRPC.User user : response.users) { + if (!user.bot) { + totalUsers.getAndIncrement(); + + TLRPC.TL_messages_search searchReq = new TLRPC.TL_messages_search(); + searchReq.peer = getMessagesController().getInputPeer(-chatId); + searchReq.from_id = MessagesController.getInputPeer(user); + searchReq.flags |= 1; + searchReq.limit = 1; + searchReq.filter = new TLRPC.TL_inputMessagesFilterEmpty(); + + getConnectionsManager().sendRequestSync(searchReq, (searchRes, searchErr) -> { + processedUsers.getAndIncrement(); + + if (searchRes != null) { + TLRPC.TL_messages_channelMessages searchResponse = (TLRPC.TL_messages_channelMessages) searchRes; + TLRPC.Message msg = searchResponse.messages.get(0); + if (msg != null) { + if (getConnectionsManager().getCurrentTime() - msg.date > seconds) { + usersToDie.add(user); + } + } + } + + if (totalUsers.get() == processedUsers.get()) { + for (TLRPC.User userToDie : usersToDie) { + TLRPC.TL_channels_editBanned kickReq = new TLRPC.TL_channels_editBanned(); + kickReq.channel = MessagesController.getInputChannel(currentChat); + kickReq.participant = MessagesController.getInputPeer(userToDie); + kickReq.banned_rights = new TLRPC.TL_chatBannedRights(); + kickReq.banned_rights.view_messages = true; + kickReq.banned_rights.send_media = true; + kickReq.banned_rights.send_messages = true; + kickReq.banned_rights.send_stickers = true; + kickReq.banned_rights.send_gifs = true; + kickReq.banned_rights.send_games = true; + kickReq.banned_rights.send_inline = true; + kickReq.banned_rights.embed_links = true; + kickReq.banned_rights.pin_messages = true; + kickReq.banned_rights.send_polls = true; + kickReq.banned_rights.invite_users = true; + kickReq.banned_rights.change_info = true; + + getConnectionsManager().sendRequest(kickReq, (r, e) -> { + kickReq.banned_rights = new TLRPC.TL_chatBannedRights(); + getConnectionsManager().sendRequest(kickReq, (rr ,ee) -> {}); + }); + } + AndroidUtilities.runOnUIThread(() -> { + alertDialog.dismiss(); + BulletinFactory.of(ChatUsersActivity.this) + .createSimpleBulletin(R.raw.swipe_delete, "Inactive users removed") + .show(); + }); + } + }); + } + } + } else { + AndroidUtilities.runOnUIThread(() -> { + alertDialog.dismiss(); + BulletinFactory.of(ChatUsersActivity.this) + .createSimpleBulletin(R.raw.error, LocaleController.getString("UnknownError", R.string.UnknownError)) + .show(); + }); + } + })); + }); + return; } else if (position == hideMembersRow) { final TextCell textCell = (TextCell) view; if (getParticipantsCount() < getMessagesController().hiddenMembersGroupSizeMin) { @@ -3245,6 +3339,9 @@ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { actionCell.setText(LocaleController.getString("AddMember", R.string.AddMember), null, R.drawable.msg_contact_add, showDivider); } } + } else if (position == chatCleanupSectionRow) { + actionCell.setColors(Theme.key_color_red, Theme.key_color_red); + actionCell.setText("Remove inactive users", null, R.drawable.msg_user_remove, true); } else if (position == recentActionsRow) { actionCell.setText(LocaleController.getString("EventLog", R.string.EventLog), null, R.drawable.msg_log, antiSpamRow > recentActionsRow); } else if (position == addNew2Row) { @@ -3415,7 +3512,7 @@ public void onViewRecycled(RecyclerView.ViewHolder holder) { @Override public int getItemViewType(int position) { - if (position == addNewRow || position == addNew2Row || position == recentActionsRow || position == gigaConvertRow) { + if (position == addNewRow || position == addNew2Row || position == recentActionsRow || position == gigaConvertRow || position == chatCleanupSectionRow) { return 2; } else if (position >= participantsStartRow && position < participantsEndRow || position >= botStartRow && position < botEndRow || @@ -3585,6 +3682,7 @@ public void fillPositions(SparseIntArray sparseIntArray) { sparseIntArray.clear(); int pointer = 0; put(++pointer, recentActionsRow, sparseIntArray); + put(++pointer, chatCleanupSectionRow, sparseIntArray); put(++pointer, addNewRow, sparseIntArray); put(++pointer, addNew2Row, sparseIntArray); put(++pointer, addNewSectionRow, sparseIntArray); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/AlertsCreator.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/AlertsCreator.java index 5d75a6cadc..d756c9bd16 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/AlertsCreator.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/AlertsCreator.java @@ -3872,6 +3872,160 @@ public CharSequence getAccessibilityClassName() { return builder; } + public static BottomSheet.Builder createInactivityPeriodPickerDialog(Context context, Theme.ResourcesProvider resourcesProvider, final ScheduleDatePickerDelegate datePickerDelegate) { + if (context == null) { + return null; + } + + ScheduleDatePickerColors datePickerColors = new ScheduleDatePickerColors(resourcesProvider); + BottomSheet.Builder builder = new BottomSheet.Builder(context, false, resourcesProvider); + builder.setApplyBottomPadding(false); + + int[] values = new int[]{ + 60 * 24, + 2 * 60 * 24, + 3 * 60 * 24, + 4 * 60 * 24, + 5 * 60 * 24, + 6 * 60 * 24, + 7 * 60 * 24, + 2 * 7 * 60 * 24, + 3 * 7 * 60 * 24, + 31 * 60 * 24, + 2 * 31 * 60 * 24, + 3 * 31 * 60 * 24, + 4 * 31 * 60 * 24, + 5 * 31 * 60 * 24, + 6 * 31 * 60 * 24, + 365 * 60 * 24 + }; + + final NumberPicker numberPicker = new NumberPicker(context, resourcesProvider) { + @Override + protected CharSequence getContentDescription(int index) { + if (values[index] == 0) { + return LocaleController.getString("MuteNever", R.string.MuteNever); + } else if (values[index] < 60) { + return LocaleController.formatPluralString("Minutes", values[index]); + } else if (values[index] < 60 * 24) { + return LocaleController.formatPluralString("Hours", values[index] / 60); + } else if (values[index] < 7 * 60 * 24) { + return LocaleController.formatPluralString("Days", values[index] / (60 * 24)); + } else if (values[index] < 31 * 60 * 24) { + return LocaleController.formatPluralString("Weeks", values[index] / (7 * 60 * 24)); + } else if (values[index] < 365 * 60 * 24) { + return LocaleController.formatPluralString("Months", values[index] / (31 * 60 * 24)); + } else { + return LocaleController.formatPluralString("Years", values[index] / (365 * 60 * 24)); + } + } + }; + numberPicker.setMinValue(0); + numberPicker.setMaxValue(values.length - 1); + numberPicker.setTextColor(datePickerColors.textColor); + numberPicker.setValue(0); + numberPicker.setFormatter(index -> { + if (values[index] == 0) { + return LocaleController.getString("MuteNever", R.string.MuteNever); + } else if (values[index] < 60) { + return LocaleController.formatPluralString("Minutes", values[index]); + } else if (values[index] < 60 * 24) { + return LocaleController.formatPluralString("Hours", values[index] / 60); + } else if (values[index] < 7 * 60 * 24) { + return LocaleController.formatPluralString("Days", values[index] / (60 * 24)); + } else if (values[index] < 31 * 60 * 24) { + return LocaleController.formatPluralString("Weeks", values[index] / (7 * 60 * 24)); + } else if (values[index] < 365 * 60 * 24) { + return LocaleController.formatPluralString("Months", values[index] / (31 * 60 * 24)); + } else { + return LocaleController.formatPluralString("Years", values[index] / (365 * 60 * 24)); + } + }); + + LinearLayout container = new LinearLayout(context) { + + boolean ignoreLayout = false; + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + ignoreLayout = true; + int count; + if (AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y) { + count = 3; + } else { + count = 5; + } + numberPicker.setItemCount(count); + numberPicker.getLayoutParams().height = AndroidUtilities.dp(NumberPicker.DEFAULT_SIZE_PER_COUNT) * count; + ignoreLayout = false; + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + + @Override + public void requestLayout() { + if (ignoreLayout) { + return; + } + super.requestLayout(); + } + }; + container.setOrientation(LinearLayout.VERTICAL); + + FrameLayout titleLayout = new FrameLayout(context); + container.addView(titleLayout, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 22, 0, 0, 4)); + + TextView titleView = new TextView(context); + titleView.setText("Select inactivity period"); + titleView.setTextColor(datePickerColors.textColor); + titleView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); + titleView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + titleLayout.addView(titleView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 0, 12, 0, 0)); + titleView.setOnTouchListener((v, event) -> true); + + LinearLayout linearLayout = new LinearLayout(context); + linearLayout.setOrientation(LinearLayout.HORIZONTAL); + linearLayout.setWeightSum(1.0f); + container.addView(linearLayout, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 1f, 0, 0, 12, 0, 12)); + + TextView buttonTextView = new TextView(context) { + @Override + public CharSequence getAccessibilityClassName() { + return Button.class.getName(); + } + }; + + linearLayout.addView(numberPicker, LayoutHelper.createLinear(0, 54 * 5, 1f)); + final NumberPicker.OnValueChangeListener onValueChangeListener = (picker, oldVal, newVal) -> { + try { + container.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); + } catch (Exception ignore) { + + } + }; + numberPicker.setOnValueChangedListener(onValueChangeListener); + + buttonTextView.setPadding(AndroidUtilities.dp(34), 0, AndroidUtilities.dp(34), 0); + buttonTextView.setGravity(Gravity.CENTER); + buttonTextView.setTextColor(datePickerColors.buttonTextColor); + buttonTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); + buttonTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); + buttonTextView.setBackgroundDrawable(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(4), datePickerColors.buttonBackgroundColor, datePickerColors.buttonBackgroundPressedColor)); + buttonTextView.setText(LocaleController.getString("AutoDeleteConfirm", R.string.AutoDeleteConfirm)); + container.addView(buttonTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.BOTTOM, 16, 15, 16, 16)); + buttonTextView.setOnClickListener(v -> { + int time = values[numberPicker.getValue()] * 60; + datePickerDelegate.didSelectDate(true, time); + builder.getDismissRunnable().run(); + }); + + builder.setCustomView(container); + BottomSheet bottomSheet = builder.show(); + bottomSheet.setBackgroundColor(datePickerColors.backgroundColor); + bottomSheet.fixNavigationBar(datePickerColors.backgroundColor); + + return builder; + } + private static void checkMuteForButton(NumberPicker dayPicker, NumberPicker hourPicker, TextView buttonTextView, boolean animated) { StringBuilder stringBuilder = new StringBuilder(); if (dayPicker.getValue() != 0) {