mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 06:07:06 +02:00
Delete history for specific days in private chats.
This commit is contained in:
parent
aa0a9b2db9
commit
80fcffcc40
18 changed files with 211 additions and 59 deletions
|
@ -81,6 +81,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_calendar_select_days" = "Select days";
|
||||
"lng_calendar_start_tip" = "Press and hold to jump to the start.";
|
||||
"lng_calendar_end_tip" = "Press and hold to jump to the end.";
|
||||
"lng_calendar_days#one" = "{count} day";
|
||||
"lng_calendar_days#other" = "{count} days";
|
||||
|
||||
"lng_box_ok" = "OK";
|
||||
"lng_box_done" = "Done";
|
||||
|
@ -1134,6 +1136,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_sure_delete_saved_messages" = "Are you sure, you want to delete all your saved messages?\n\nThis action cannot be undone.";
|
||||
"lng_no_clear_history_channel" = "In channels you can enable auto-delete for messages.";
|
||||
"lng_no_clear_history_group" = "In public groups you can enable auto-delete for messages.";
|
||||
"lng_sure_delete_by_date_one" = "Are you sure you want to delete all messages for **{date}**?\n\nThis action cannot be undone.";
|
||||
"lng_sure_delete_by_date_many" = "Are you sure you want to delete all messages for the **{days}**?\n\nThis action cannot be undone.";
|
||||
"lng_sure_delete_selected_days#one" = "{count} selected day";
|
||||
"lng_sure_delete_selected_days#other" = "{count} selected days";
|
||||
|
||||
"lng_message_empty" = "Empty Message";
|
||||
"lng_message_unsupported" = "This message is not supported by your version of Telegram Desktop. Please update to the latest version in Settings, or install it from {link}";
|
||||
|
|
|
@ -54,6 +54,18 @@ DeleteMessagesBox::DeleteMessagesBox(
|
|||
Expects(!_ids.empty());
|
||||
}
|
||||
|
||||
DeleteMessagesBox::DeleteMessagesBox(
|
||||
QWidget*,
|
||||
not_null<PeerData*> peer,
|
||||
QDate firstDayToDelete,
|
||||
QDate lastDayToDelete)
|
||||
: _session(&peer->session())
|
||||
, _wipeHistoryPeer(peer)
|
||||
, _wipeHistoryJustClear(true)
|
||||
, _wipeHistoryFirstToDelete(firstDayToDelete)
|
||||
, _wipeHistoryLastToDelete(lastDayToDelete) {
|
||||
}
|
||||
|
||||
DeleteMessagesBox::DeleteMessagesBox(
|
||||
QWidget*,
|
||||
not_null<PeerData*> peer,
|
||||
|
@ -73,7 +85,27 @@ void DeleteMessagesBox::prepare() {
|
|||
auto deleteStyle = &st::defaultBoxButton;
|
||||
auto canDelete = true;
|
||||
if (const auto peer = _wipeHistoryPeer) {
|
||||
if (_wipeHistoryJustClear) {
|
||||
if (!_wipeHistoryFirstToDelete.isNull()) {
|
||||
details = (_wipeHistoryFirstToDelete
|
||||
== _wipeHistoryLastToDelete)
|
||||
? tr::lng_sure_delete_by_date_one(
|
||||
tr::now,
|
||||
lt_date,
|
||||
TextWithEntities{
|
||||
langDayOfMonthFull(_wipeHistoryFirstToDelete) },
|
||||
Ui::Text::RichLangValue)
|
||||
: tr::lng_sure_delete_by_date_many(
|
||||
tr::now,
|
||||
lt_days,
|
||||
tr::lng_sure_delete_selected_days(
|
||||
tr::now,
|
||||
lt_count,
|
||||
_wipeHistoryFirstToDelete.daysTo(
|
||||
_wipeHistoryLastToDelete) + 1,
|
||||
Ui::Text::WithEntities),
|
||||
Ui::Text::RichLangValue);
|
||||
deleteStyle = &st::attentionBoxButton;
|
||||
} else if (_wipeHistoryJustClear) {
|
||||
const auto isChannel = peer->isBroadcast();
|
||||
const auto isPublicGroup = peer->isMegagroup()
|
||||
&& peer->asChannel()->isPublic();
|
||||
|
@ -397,16 +429,41 @@ void DeleteMessagesBox::keyPressEvent(QKeyEvent *e) {
|
|||
|
||||
void DeleteMessagesBox::deleteAndClear() {
|
||||
const auto revoke = _revoke ? _revoke->checked() : false;
|
||||
if (const auto peer = _wipeHistoryPeer) {
|
||||
const auto session = _session;
|
||||
const auto invokeCallbackAndClose = [&] {
|
||||
// deleteMessages can initiate closing of the current section,
|
||||
// which will cause this box to be destroyed.
|
||||
const auto weak = Ui::MakeWeak(this);
|
||||
if (const auto callback = _deleteConfirmedCallback) {
|
||||
callback();
|
||||
}
|
||||
if (const auto strong = weak.data()) {
|
||||
strong->closeBox();
|
||||
}
|
||||
};
|
||||
if (!_wipeHistoryFirstToDelete.isNull()) {
|
||||
const auto peer = _wipeHistoryPeer;
|
||||
const auto firstDayToDelete = _wipeHistoryFirstToDelete;
|
||||
const auto lastDayToDelete = _wipeHistoryLastToDelete;
|
||||
|
||||
invokeCallbackAndClose();
|
||||
session->data().histories().deleteMessagesByDates(
|
||||
session->data().history(peer),
|
||||
firstDayToDelete,
|
||||
lastDayToDelete,
|
||||
revoke);
|
||||
session->data().sendHistoryChangeNotifications();
|
||||
return;
|
||||
} else if (const auto peer = _wipeHistoryPeer) {
|
||||
const auto justClear = _wipeHistoryJustClear;
|
||||
closeBox();
|
||||
invokeCallbackAndClose();
|
||||
|
||||
if (justClear) {
|
||||
peer->session().api().clearHistory(peer, revoke);
|
||||
session->api().clearHistory(peer, revoke);
|
||||
} else {
|
||||
for (const auto &controller : peer->session().windows()) {
|
||||
for (const auto &controller : session->windows()) {
|
||||
if (controller->activeChatCurrent().peer() == peer) {
|
||||
Ui::showChatsList(&peer->session());
|
||||
Ui::showChatsList(session);
|
||||
}
|
||||
}
|
||||
// Don't delete old history by default,
|
||||
|
@ -415,7 +472,7 @@ void DeleteMessagesBox::deleteAndClear() {
|
|||
//if (const auto from = peer->migrateFrom()) {
|
||||
// peer->session().api().deleteConversation(from, false);
|
||||
//}
|
||||
peer->session().api().deleteConversation(peer, revoke);
|
||||
session->api().deleteConversation(peer, revoke);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -441,19 +498,8 @@ void DeleteMessagesBox::deleteAndClear() {
|
|||
}
|
||||
}
|
||||
|
||||
if (_deleteConfirmedCallback) {
|
||||
_deleteConfirmedCallback();
|
||||
}
|
||||
|
||||
// deleteMessages can initiate closing of the current section,
|
||||
// which will cause this box to be destroyed.
|
||||
const auto session = _session;
|
||||
const auto weak = Ui::MakeWeak(this);
|
||||
|
||||
session->data().histories().deleteMessages(_ids, revoke);
|
||||
|
||||
if (const auto strong = weak.data()) {
|
||||
strong->closeBox();
|
||||
}
|
||||
const auto ids = _ids;
|
||||
invokeCallbackAndClose();
|
||||
session->data().histories().deleteMessages(ids, revoke);
|
||||
session->data().sendHistoryChangeNotifications();
|
||||
}
|
||||
|
|
|
@ -29,6 +29,11 @@ public:
|
|||
QWidget*,
|
||||
not_null<Main::Session*> session,
|
||||
MessageIdsList &&selected);
|
||||
DeleteMessagesBox(
|
||||
QWidget*,
|
||||
not_null<PeerData*> peer,
|
||||
QDate firstDayToDelete,
|
||||
QDate lastDayToDelete);
|
||||
DeleteMessagesBox(QWidget*, not_null<PeerData*> peer, bool justClear);
|
||||
|
||||
void setDeleteConfirmedCallback(Fn<void()> callback) {
|
||||
|
@ -56,6 +61,8 @@ private:
|
|||
|
||||
PeerData * const _wipeHistoryPeer = nullptr;
|
||||
const bool _wipeHistoryJustClear = false;
|
||||
const QDate _wipeHistoryFirstToDelete;
|
||||
const QDate _wipeHistoryLastToDelete;
|
||||
const MessageIdsList _ids;
|
||||
UserData *_moderateFrom = nullptr;
|
||||
ChannelData *_moderateInChannel = nullptr;
|
||||
|
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_chat.h"
|
||||
#include "data/data_folder.h"
|
||||
#include "data/data_scheduled_messages.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "main/main_session.h"
|
||||
#include "window/notifications_manager.h"
|
||||
#include "history/history.h"
|
||||
|
@ -708,6 +709,58 @@ void Histories::deleteAllMessages(
|
|||
});
|
||||
}
|
||||
|
||||
void Histories::deleteMessagesByDates(
|
||||
not_null<History*> history,
|
||||
QDate firstDayToDelete,
|
||||
QDate lastDayToDelete,
|
||||
bool revoke) {
|
||||
const auto firstSecondToDelete = base::unixtime::serialize(
|
||||
{ firstDayToDelete, QTime(0, 0) }
|
||||
);
|
||||
const auto lastSecondToDelete = base::unixtime::serialize(
|
||||
{ lastDayToDelete, QTime(23, 59, 59) }
|
||||
);
|
||||
deleteMessagesByDates(
|
||||
history,
|
||||
firstSecondToDelete - 1,
|
||||
lastSecondToDelete + 1,
|
||||
revoke);
|
||||
}
|
||||
|
||||
void Histories::deleteMessagesByDates(
|
||||
not_null<History*> history,
|
||||
TimeId minDate,
|
||||
TimeId maxDate,
|
||||
bool revoke) {
|
||||
sendRequest(history, RequestType::Delete, [=](Fn<void()> finish) {
|
||||
const auto peer = history->peer;
|
||||
const auto fail = [=](const MTP::Error &error) {
|
||||
finish();
|
||||
};
|
||||
using Flag = MTPmessages_DeleteHistory::Flag;
|
||||
const auto flags = Flag::f_just_clear
|
||||
| Flag::f_min_date
|
||||
| Flag::f_max_date
|
||||
| (revoke ? Flag::f_revoke : Flag(0));
|
||||
return session().api().request(MTPmessages_DeleteHistory(
|
||||
MTP_flags(flags),
|
||||
peer->input,
|
||||
MTP_int(0),
|
||||
MTP_int(minDate),
|
||||
MTP_int(maxDate)
|
||||
)).done([=](const MTPmessages_AffectedHistory &result) {
|
||||
const auto offset = session().api().applyAffectedHistory(
|
||||
peer,
|
||||
result);
|
||||
if (offset > 0) {
|
||||
deleteMessagesByDates(history, minDate, maxDate, revoke);
|
||||
}
|
||||
finish();
|
||||
}).fail(fail).send();
|
||||
});
|
||||
history->destroyMessagesByDates(minDate, maxDate);
|
||||
}
|
||||
|
||||
void Histories::deleteMessages(const MessageIdsList &ids, bool revoke) {
|
||||
auto remove = std::vector<not_null<HistoryItem*>>();
|
||||
remove.reserve(ids.size());
|
||||
|
|
|
@ -71,6 +71,17 @@ public:
|
|||
bool justClear,
|
||||
bool revoke);
|
||||
|
||||
void deleteMessagesByDates(
|
||||
not_null<History*> history,
|
||||
QDate firstDayToDelete,
|
||||
QDate lastDayToDelete,
|
||||
bool revoke);
|
||||
void deleteMessagesByDates(
|
||||
not_null<History*> history,
|
||||
TimeId minDate,
|
||||
TimeId maxDate,
|
||||
bool revoke);
|
||||
|
||||
void deleteMessages(const MessageIdsList &ids, bool revoke);
|
||||
|
||||
int sendRequest(
|
||||
|
|
|
@ -284,7 +284,7 @@ Widget::Widget(
|
|||
}, lifetime());
|
||||
|
||||
_cancelSearch->setClickedCallback([this] { onCancelSearch(); });
|
||||
_jumpToDate->entity()->setClickedCallback([this] { showJumpToDate(); });
|
||||
_jumpToDate->entity()->setClickedCallback([this] { showCalendar(); });
|
||||
_chooseFromUser->entity()->setClickedCallback([this] { showSearchFrom(); });
|
||||
rpl::single(
|
||||
rpl::empty_value()
|
||||
|
@ -1453,9 +1453,9 @@ void Widget::clearSearchCache() {
|
|||
cancelSearchRequest();
|
||||
}
|
||||
|
||||
void Widget::showJumpToDate() {
|
||||
void Widget::showCalendar() {
|
||||
if (_searchInChat) {
|
||||
controller()->showJumpToDate(_searchInChat, QDate());
|
||||
controller()->showCalendar(_searchInChat, QDate());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -150,7 +150,7 @@ private:
|
|||
void setupMainMenuToggle();
|
||||
bool searchForPeersRequired(const QString &query) const;
|
||||
void setSearchInChat(Key chat, PeerData *from = nullptr);
|
||||
void showJumpToDate();
|
||||
void showCalendar();
|
||||
void showSearchFrom();
|
||||
void showMainMenu();
|
||||
void clearSearchCache();
|
||||
|
|
|
@ -462,6 +462,20 @@ void History::destroyMessage(not_null<HistoryItem*> item) {
|
|||
}
|
||||
}
|
||||
|
||||
void History::destroyMessagesByDates(TimeId minDate, TimeId maxDate) {
|
||||
auto toDestroy = std::vector<not_null<HistoryItem*>>();
|
||||
for (const auto &message : _messages) {
|
||||
if (message->isRegular()
|
||||
&& message->date() > minDate
|
||||
&& message->date() < maxDate) {
|
||||
toDestroy.push_back(message.get());
|
||||
}
|
||||
}
|
||||
for (const auto item : toDestroy) {
|
||||
item->destroy();
|
||||
}
|
||||
}
|
||||
|
||||
void History::unpinAllMessages() {
|
||||
session().storage().remove(
|
||||
Storage::SharedMediaRemoveAll(
|
||||
|
|
|
@ -132,6 +132,7 @@ public:
|
|||
std::forward<Args>(args)...)).get());
|
||||
}
|
||||
void destroyMessage(not_null<HistoryItem*> item);
|
||||
void destroyMessagesByDates(TimeId minDate, TimeId maxDate);
|
||||
|
||||
void unpinAllMessages();
|
||||
|
||||
|
|
|
@ -6782,13 +6782,10 @@ void HistoryWidget::confirmDeleteSelected() {
|
|||
if (items.empty()) {
|
||||
return;
|
||||
}
|
||||
const auto weak = Ui::MakeWeak(this);
|
||||
auto box = Box<DeleteMessagesBox>(&session(), std::move(items));
|
||||
box->setDeleteConfirmedCallback([=] {
|
||||
if (const auto strong = weak.data()) {
|
||||
strong->clearSelected();
|
||||
}
|
||||
});
|
||||
box->setDeleteConfirmedCallback(crl::guard(this, [=] {
|
||||
clearSelected();
|
||||
}));
|
||||
controller()->show(std::move(box));
|
||||
}
|
||||
|
||||
|
|
|
@ -689,16 +689,13 @@ bool AddDeleteSelectedAction(
|
|||
}
|
||||
|
||||
menu->addAction(tr::lng_context_delete_selected(tr::now), [=] {
|
||||
const auto weak = Ui::MakeWeak(list);
|
||||
auto items = ExtractIdsList(request.selectedItems);
|
||||
auto box = Box<DeleteMessagesBox>(
|
||||
&request.navigation->session(),
|
||||
std::move(items));
|
||||
box->setDeleteConfirmedCallback([=] {
|
||||
if (const auto strong = weak.data()) {
|
||||
strong->cancelSelection();
|
||||
}
|
||||
});
|
||||
box->setDeleteConfirmedCallback(crl::guard(list, [=] {
|
||||
list->cancelSelection();
|
||||
}));
|
||||
request.navigation->parentController()->show(std::move(box));
|
||||
});
|
||||
return true;
|
||||
|
|
|
@ -3027,15 +3027,12 @@ void ConfirmDeleteSelectedItems(not_null<ListWidget*> widget) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
const auto weak = Ui::MakeWeak(widget);
|
||||
auto box = Box<DeleteMessagesBox>(
|
||||
&widget->controller()->session(),
|
||||
widget->getSelectedIds());
|
||||
box->setDeleteConfirmedCallback([=] {
|
||||
if (const auto strong = weak.data()) {
|
||||
strong->cancelSelection();
|
||||
}
|
||||
});
|
||||
box->setDeleteConfirmedCallback(crl::guard(widget, [=] {
|
||||
widget->cancelSelection();
|
||||
}));
|
||||
widget->controller()->show(std::move(box));
|
||||
}
|
||||
|
||||
|
|
|
@ -544,11 +544,9 @@ void TopBar::performDelete() {
|
|||
auto box = Box<DeleteMessagesBox>(
|
||||
&_navigation->session(),
|
||||
std::move(items));
|
||||
box->setDeleteConfirmedCallback([weak = Ui::MakeWeak(this)] {
|
||||
if (weak) {
|
||||
weak->_cancelSelectionClicks.fire({});
|
||||
}
|
||||
});
|
||||
box->setDeleteConfirmedCallback(crl::guard(this, [=] {
|
||||
_cancelSelectionClicks.fire({});
|
||||
}));
|
||||
_navigation->parentController()->show(std::move(box));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1715,12 +1715,9 @@ void ListWidget::forwardItems(MessageIdsList &&items) {
|
|||
|
||||
void ListWidget::deleteSelected() {
|
||||
if (const auto box = deleteItems(collectSelectedIds())) {
|
||||
const auto weak = Ui::MakeWeak(this);
|
||||
box->setDeleteConfirmedCallback([=]{
|
||||
if (const auto strong = weak.data()) {
|
||||
strong->clearSelected();
|
||||
}
|
||||
});
|
||||
box->setDeleteConfirmedCallback(crl::guard(this, [=]{
|
||||
clearSelected();
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -693,7 +693,10 @@ CalendarBox::Title::Title(
|
|||
} else if (!_context->selectedMin()) {
|
||||
setText(tr::lng_calendar_select_days(tr::now));
|
||||
} else {
|
||||
setText(QString::number(1 + *_context->selectedMax() - *_context->selectedMin())); // #TODO calendar
|
||||
setText(tr::lng_calendar_days(
|
||||
tr::now,
|
||||
lt_count,
|
||||
(1 + *_context->selectedMax() - *_context->selectedMin())));
|
||||
}
|
||||
}, lifetime());
|
||||
}
|
||||
|
@ -803,6 +806,16 @@ void CalendarBox::toggleSelectionMode(bool enabled) {
|
|||
_context->toggleSelectionMode(enabled);
|
||||
}
|
||||
|
||||
QDate CalendarBox::selectedFirstDate() const {
|
||||
const auto min = _context->selectedMin();
|
||||
return min.has_value() ? _context->dateFromIndex(*min) : QDate();
|
||||
}
|
||||
|
||||
QDate CalendarBox::selectedLastDate() const {
|
||||
const auto max = _context->selectedMax();
|
||||
return max.has_value() ? _context->dateFromIndex(*max) : QDate();
|
||||
}
|
||||
|
||||
void CalendarBox::showJumpTooltip(not_null<IconButton*> button) {
|
||||
_tooltipButton = button;
|
||||
Ui::Tooltip::Show(kTooltipDelay, this);
|
||||
|
|
|
@ -50,6 +50,9 @@ public:
|
|||
|
||||
void toggleSelectionMode(bool enabled);
|
||||
|
||||
[[nodiscard]] QDate selectedFirstDate() const;
|
||||
[[nodiscard]] QDate selectedLastDate() const;
|
||||
|
||||
protected:
|
||||
void prepare() override;
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "boxes/add_contact_box.h"
|
||||
#include "boxes/peers/edit_peer_info_box.h"
|
||||
#include "boxes/peer_list_controllers.h"
|
||||
#include "boxes/delete_messages_box.h"
|
||||
#include "window/window_adaptive.h"
|
||||
#include "window/window_controller.h"
|
||||
#include "window/main_window.h"
|
||||
|
@ -151,7 +152,7 @@ void DateClickHandler::setDate(QDate date) {
|
|||
void DateClickHandler::onClick(ClickContext context) const {
|
||||
const auto my = context.other.value<ClickHandlerContext>();
|
||||
if (const auto window = my.sessionWindow.get()) {
|
||||
window->showJumpToDate(_chat, _date);
|
||||
window->showCalendar(_chat, _date);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1146,7 +1147,7 @@ void SessionController::startOrJoinGroupCall(
|
|||
}
|
||||
}
|
||||
|
||||
void SessionController::showJumpToDate(Dialogs::Key chat, QDate requestedDate) {
|
||||
void SessionController::showCalendar(Dialogs::Key chat, QDate requestedDate) {
|
||||
const auto history = chat.history();
|
||||
if (!history) {
|
||||
return;
|
||||
|
@ -1248,7 +1249,18 @@ void SessionController::showJumpToDate(Dialogs::Key chat, QDate requestedDate) {
|
|||
});
|
||||
auto text = tr::lng_profile_clear_history();
|
||||
const auto button = box->addLeftButton(std::move(text), [=] {
|
||||
|
||||
const auto firstDate = box->selectedFirstDate();
|
||||
const auto lastDate = box->selectedLastDate();
|
||||
if (!firstDate.isNull()) {
|
||||
auto confirm = Box<DeleteMessagesBox>(
|
||||
history->peer,
|
||||
firstDate,
|
||||
lastDate);
|
||||
confirm->setDeleteConfirmedCallback(crl::guard(box, [=] {
|
||||
box->closeBox();
|
||||
}));
|
||||
box->getDelegate()->show(std::move(confirm));
|
||||
}
|
||||
}, (*selected > 0) ? st::attentionBoxButton : buttonState->disabled);
|
||||
if (!*selected) {
|
||||
button->setPointerCursor(false);
|
||||
|
|
|
@ -363,7 +363,7 @@ public:
|
|||
}
|
||||
void removeLayerBlackout();
|
||||
|
||||
void showJumpToDate(
|
||||
void showCalendar(
|
||||
Dialogs::Key chat,
|
||||
QDate requestedDate);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue