chore: refactor a bit

This commit is contained in:
AlexeyZavar 2024-09-23 16:46:41 +03:00
parent 625f9ef816
commit 3d91d2c80a
22 changed files with 366 additions and 214 deletions

View file

@ -234,10 +234,12 @@ void addDeletedMessage(const DeletedMessage &message) {
}
}
std::vector<DeletedMessage> getDeletedMessages(ID dialogId, ID minId, ID maxId, int totalLimit) {
std::vector<DeletedMessage> getDeletedMessages(ID userId, ID dialogId, ID topicId, ID minId, ID maxId, int totalLimit) {
return storage.get_all<DeletedMessage>(
where(
column<DeletedMessage>(&DeletedMessage::userId) == userId and
column<DeletedMessage>(&DeletedMessage::dialogId) == dialogId and
(column<DeletedMessage>(&DeletedMessage::topicId) == topicId or topicId == 0) and
(column<DeletedMessage>(&DeletedMessage::messageId) > minId or minId == 0) and
(column<DeletedMessage>(&DeletedMessage::messageId) < maxId or maxId == 0)
),
@ -246,11 +248,13 @@ std::vector<DeletedMessage> getDeletedMessages(ID dialogId, ID minId, ID maxId,
);
}
bool hasDeletedMessages(ID dialogId) {
bool hasDeletedMessages(ID userId, ID dialogId, ID topicId) {
try {
return storage.count<DeletedMessage>(
where(
column<DeletedMessage>(&DeletedMessage::dialogId) == dialogId
column<DeletedMessage>(&DeletedMessage::userId) == userId and
column<DeletedMessage>(&DeletedMessage::dialogId) == dialogId and
(column<DeletedMessage>(&DeletedMessage::topicId) == topicId or topicId == 0)
)
) > 0;
} catch (std::exception &ex) {

View file

@ -17,7 +17,7 @@ std::vector<EditedMessage> getEditedMessages(ID userId, ID dialogId, ID messageI
bool hasRevisions(ID userId, ID dialogId, ID messageId);
void addDeletedMessage(const DeletedMessage &message);
std::vector<DeletedMessage> getDeletedMessages(ID dialogId, ID minId, ID maxId, int totalLimit);
bool hasDeletedMessages(ID dialogId);
std::vector<DeletedMessage> getDeletedMessages(ID userId, ID dialogId, ID topicId, ID minId, ID maxId, int totalLimit);
bool hasDeletedMessages(ID userId, ID dialogId, ID topicId);
}

View file

@ -30,12 +30,14 @@ public:
std::string fwdName;
int fwdDate;
std::string fwdPostAuthor;
std::string postAuthor;
int replyFlags;
int replyMessageId;
ID replyPeerId;
int replyTopId;
bool replyForumTopic;
std::vector<char> replySerialized;
std::vector<char> replyMarkupSerialized;
int entityCreateDate;
std::string text;
std::vector<char> textEntities;

View file

@ -35,26 +35,42 @@ std::vector<AyuMessageBase> convertToBase(const std::vector<DerivedMessage> &mes
}
void map(not_null<HistoryItem*> item, AyuMessageBase &message) {
message.userId = item->history()->owner().session().userId().bare;
const ID userId = item->history()->owner().session().userId().bare & PeerId::kChatTypeMask;
message.userId = userId;
message.dialogId = getDialogIdFromPeer(item->history()->peer);
message.groupedId = item->groupId().value;
message.peerId = item->from()->id.value; // todo: ???
message.fromId = item->from()->id.value;
if (auto topic = item->history()->asTopic()) {
message.topicId = topic->rootId().bare;
message.groupedId = item->groupId().raw();
message.peerId = item->history()->peer->id.value & PeerId::kChatTypeMask;
message.fromId = item->from()->id.value & PeerId::kChatTypeMask;
if (item->topic()) {
message.topicId = item->topicRootId().bare;
}
message.messageId = item->id.bare;
message.date = item->date();
message.flags = AyuMapper::mapItemFlagsToMTPFlags(item);
if (auto edited = item->Get<HistoryMessageEdited>()) {
if (const auto edited = item->Get<HistoryMessageEdited>()) {
message.editDate = edited->date;
} else {
message.editDate = base::unixtime::now();
}
message.views = item->viewsCount();
message.entityCreateDate = base::unixtime::now(); // todo: rework
message.fwdFlags = 0;
message.fwdFromId = 0;
// message.fwdName
// message.fwdPostAuthor
if (const auto msgsigned = item->Get<HistoryMessageSigned>()) {
message.postAuthor = msgsigned->author.toStdString();
}
message.replyFlags = 0;
message.replyMessageId = 0;
message.replyPeerId = 0;
message.replyTopId = 0;
message.replyForumTopic = 0;
// message.replySerialized
// message.replyMarkupSerialized
message.entityCreateDate = base::unixtime::now();
auto serializedText = AyuMapper::serializeTextWithEntities(item);
message.text = serializedText.first;
@ -62,12 +78,12 @@ void map(not_null<HistoryItem*> item, AyuMessageBase &message) {
// todo: implement mapping
message.mediaPath = "/";
// message.hqThumbPath
message.documentType = DOCUMENT_TYPE_NONE;
// message.documentSerialized;
// message.thumbsSerialized;
// message.documentAttributesSerialized;
// message.mimeType;
// message.documentSerialized
// message.thumbsSerialized
// message.documentAttributesSerialized
// message.mimeType
}
void addEditedMessage(HistoryMessageEdition &edition, not_null<HistoryItem*> item) {
@ -82,17 +98,17 @@ void addEditedMessage(HistoryMessageEdition &edition, not_null<HistoryItem*> ite
}
std::vector<AyuMessageBase> getEditedMessages(not_null<HistoryItem*> item, ID minId, ID maxId, int totalLimit) {
auto userId = item->history()->owner().session().userId().bare;
auto dialogId = getDialogIdFromPeer(item->history()->peer);
auto msgId = item->id.bare;
const ID userId = item->history()->owner().session().userId().bare & PeerId::kChatTypeMask;
const auto dialogId = getDialogIdFromPeer(item->history()->peer);
const auto msgId = item->id.bare;
return convertToBase(AyuDatabase::getEditedMessages(userId, dialogId, msgId, minId, maxId, totalLimit));
}
bool hasRevisions(not_null<HistoryItem*> item) {
auto userId = item->history()->owner().session().userId().bare;
auto dialogId = getDialogIdFromPeer(item->history()->peer);
auto msgId = item->id.bare;
const ID userId = item->history()->owner().session().userId().bare & PeerId::kChatTypeMask;
const auto dialogId = getDialogIdFromPeer(item->history()->peer);
const auto msgId = item->id.bare;
return AyuDatabase::hasRevisions(userId, dialogId, msgId);
}
@ -108,12 +124,16 @@ void addDeletedMessage(not_null<HistoryItem*> item) {
AyuDatabase::addDeletedMessage(message);
}
std::vector<AyuMessageBase> getDeletedMessages(not_null<PeerData*> peer, ID minId, ID maxId, int totalLimit) {
return convertToBase(AyuDatabase::getDeletedMessages(getDialogIdFromPeer(peer), minId, maxId, totalLimit));
std::vector<AyuMessageBase>
getDeletedMessages(not_null<PeerData*> peer, ID topicId, ID minId, ID maxId, int totalLimit) {
const ID userId = peer->session().userId().bare & PeerId::kChatTypeMask;
return convertToBase(
AyuDatabase::getDeletedMessages(userId, getDialogIdFromPeer(peer), topicId, minId, maxId, totalLimit));
}
bool hasDeletedMessages(not_null<PeerData*> peer) {
return AyuDatabase::hasDeletedMessages(getDialogIdFromPeer(peer));
bool hasDeletedMessages(not_null<PeerData*> peer, ID topicId) {
const ID userId = peer->session().userId().bare & PeerId::kChatTypeMask;
return AyuDatabase::hasDeletedMessages(userId, getDialogIdFromPeer(peer), topicId);
}
}

View file

@ -17,7 +17,7 @@ std::vector<AyuMessageBase> getEditedMessages(not_null<HistoryItem*> item, ID mi
bool hasRevisions(not_null<HistoryItem*> item);
void addDeletedMessage(not_null<HistoryItem*> item);
std::vector<AyuMessageBase> getDeletedMessages(not_null<PeerData*> peer, ID minId, ID maxId, int totalLimit);
bool hasDeletedMessages(not_null<PeerData*> peer);
std::vector<AyuMessageBase> getDeletedMessages(not_null<PeerData*> peer, ID topicId, ID minId, ID maxId, int totalLimit);
bool hasDeletedMessages(not_null<PeerData*> peer, ID topicId);
}

View file

@ -6,6 +6,7 @@
// Copyright @Radolyn, 2024
#include "ayu/ui/context_menu/context_menu.h"
#include "apiwrap.h"
#include "lang_auto.h"
#include "mainwidget.h"
#include "mainwindow.h"
@ -26,6 +27,11 @@
#include "ayu/ui/message_history/history_section.h"
#include "ayu/utils/telegram_helpers.h"
#include "base/unixtime.h"
#include "data/data_channel.h"
#include "data/data_user.h"
#include "data/data_chat.h"
#include "data/data_forum_topic.h"
#include "data/data_session.h"
#include "history/view/history_view_context_menu.h"
#include "history/view/history_view_element.h"
#include "window/window_session_controller.h"
@ -37,14 +43,17 @@ bool needToShowItem(int state) {
}
void AddDeletedMessagesActions(PeerData *peerData,
Data::Thread *thread,
not_null<Window::SessionController*> sessionController,
const Dialogs::EntryState &entryState,
const Window::PeerMenuCallback &addCallback) {
if (!peerData) {
return;
}
const auto has = AyuMessages::hasDeletedMessages(peerData);
const auto topic = peerData->isForum() ? thread->asTopic() : nullptr;
const auto topicId = topic ? topic->rootId().bare : 0;
const auto has = AyuMessages::hasDeletedMessages(peerData, topicId);
if (!has) {
return;
}
@ -53,11 +62,91 @@ void AddDeletedMessagesActions(PeerData *peerData,
[=]
{
sessionController->session().tryResolveWindow()
->showSection(std::make_shared<MessageHistory::SectionMemento>(peerData));
->showSection(std::make_shared<MessageHistory::SectionMemento>(peerData, nullptr, topicId));
},
&st::menuIconArchive);
}
void AddJumpToBeginningAction(PeerData *peerData,
Data::Thread *thread,
not_null<Window::SessionController*> sessionController,
const Window::PeerMenuCallback &addCallback) {
const auto user = peerData->asUser();
const auto group = peerData->isChat() ? peerData->asChat() : nullptr;
const auto chat = peerData->isMegagroup()
? peerData->asMegagroup()
: peerData->isChannel()
? peerData->asChannel()
: nullptr;
const auto topic = peerData->isForum() ? thread->asTopic() : nullptr;
if (!user && !group && !chat && !topic) {
return;
}
if (topic && topic->creating()) {
return;
}
const auto controller = sessionController;
const auto jumpToDate = [=](auto history, auto callback)
{
const auto weak = base::make_weak(controller);
controller->session().api().resolveJumpToDate(
history,
QDate(2013, 8, 1),
[=](not_null<PeerData*> peer, MsgId id)
{
if (const auto strong = weak.get()) {
callback(peer, id);
}
});
};
const auto showPeerHistory = [=](auto peer, MsgId id)
{
controller->showPeerHistory(
peer,
Window::SectionShow::Way::Forward,
id);
};
const auto showTopic = [=](auto topic, MsgId id)
{
controller->showTopic(
topic,
id,
Window::SectionShow::Way::Forward);
};
addCallback(
tr::ayu_JumpToBeginning(tr::now),
[=]
{
if (user) {
jumpToDate(controller->session().data().history(user), showPeerHistory);
} else if (group && !chat) {
jumpToDate(controller->session().data().history(group), showPeerHistory);
} else if (chat && !topic) {
if (!chat->migrateFrom() && chat->availableMinId() == 1) {
showPeerHistory(chat, 1);
} else {
jumpToDate(controller->session().data().history(chat), showPeerHistory);
}
} else if (topic) {
if (topic->isGeneral()) {
showTopic(topic, 1);
} else {
jumpToDate(
topic,
[=](not_null<PeerData*>, MsgId id)
{
showTopic(topic, id);
});
}
}
},
&st::ayuMenuIconToBeginning);
}
void AddHistoryAction(not_null<Ui::PopupMenu*> menu, HistoryItem *item) {
if (AyuMessages::hasRevisions(item)) {
menu->addAction(tr::ayu_EditsHistoryMenuText(tr::now),
@ -65,7 +154,7 @@ void AddHistoryAction(not_null<Ui::PopupMenu*> menu, HistoryItem *item) {
{
item->history()->session().tryResolveWindow()
->showSection(
std::make_shared<MessageHistory::SectionMemento>(item->history()->peer, item));
std::make_shared<MessageHistory::SectionMemento>(item->history()->peer, item, 0));
},
&st::ayuEditsHistoryIcon);
}
@ -332,7 +421,7 @@ void AddMessageDetailsAction(not_null<Ui::PopupMenu*> menu, HistoryItem *item) {
}
void AddReadUntilAction(not_null<Ui::PopupMenu*> menu, HistoryItem *item) {
if (item->isLocal() || item->isService() || item->out()) {
if (item->isLocal() || item->isService() || item->out() || item->isDeleted()) {
return;
}

View file

@ -16,10 +16,15 @@ namespace AyuUi {
bool needToShowItem(int state);
void AddDeletedMessagesActions(PeerData *peerData,
Data::Thread *thread,
not_null<Window::SessionController*> sessionController,
const Dialogs::EntryState &entryState,
const Window::PeerMenuCallback &addCallback);
void AddJumpToBeginningAction(PeerData *peerData,
Data::Thread *thread,
not_null<Window::SessionController*> sessionController,
const Window::PeerMenuCallback &addCallback);
void AddHistoryAction(not_null<Ui::PopupMenu*> menu, HistoryItem *item);
void AddHideMessageAction(not_null<Ui::PopupMenu*> menu, HistoryItem *item);
void AddUserMessagesAction(not_null<Ui::PopupMenu*> menu, HistoryItem *item);

View file

@ -246,11 +246,13 @@ InnerWidget::InnerWidget(
QWidget *parent,
not_null<Window::SessionController*> controller,
not_null<PeerData*> peer,
HistoryItem *item)
HistoryItem *item,
ID topicId)
: RpWidget(parent),
_controller(controller),
_peer(peer),
_item(item),
_topicId(topicId),
_history(peer->owner().history(peer)),
_api(&_peer->session().mtp()),
_pathGradient(
@ -668,7 +670,7 @@ void InnerWidget::preloadMore(Direction direction) {
messages = AyuMessages::getEditedMessages(_item, minId, maxId, perPage);
} else {
// viewing deleted messages
messages = AyuMessages::getDeletedMessages(_peer, minId, maxId, perPage);
messages = AyuMessages::getDeletedMessages(_peer, _topicId, minId, maxId, perPage);
}
crl::on_main([=]

View file

@ -52,7 +52,8 @@ public:
QWidget *parent,
not_null<Window::SessionController*> controller,
not_null<PeerData*> peer,
HistoryItem *item);
HistoryItem *item,
ID topicId);
[[nodiscard]] Main::Session &session() const;
@ -251,6 +252,7 @@ private:
const not_null<Window::SessionController*> _controller;
const not_null<PeerData*> _peer;
HistoryItem *_item;
ID _topicId;
const not_null<History*> _history;
MTP::Sender _api;
@ -283,8 +285,8 @@ private:
int _scrollDateLastItemTop = 0;
// Up - max, Down - min.
uint64 _maxId = 0;
uint64 _minId = 0;
ID _maxId = 0;
ID _minId = 0;
// Don't load anything until the memento was read.
bool _upLoaded = true;

View file

@ -63,7 +63,7 @@ object_ptr<Window::SectionWidget> SectionMemento::createWidget(
if (column == Window::Column::Third) {
return nullptr;
}
auto result = object_ptr<Widget>(parent, controller, _peer, _item);
auto result = object_ptr<Widget>(parent, controller, _peer, _item, _topicId);
result->setInternalState(geometry, this);
return result;
}
@ -142,12 +142,14 @@ Widget::Widget(
QWidget *parent,
not_null<Window::SessionController*> controller,
not_null<PeerData*> peer,
HistoryItem *item)
HistoryItem *item,
ID topicId)
: Window::SectionWidget(parent, controller, rpl::single<PeerData*>(peer)),
_scroll(this, st::historyScroll, false),
_fixedBar(this, controller, peer),
_fixedBarShadow(this),
_item(item) {
_item(item),
_topicId(topicId) {
_fixedBar->move(0, 0);
_fixedBar->resizeToWidth(width());
_fixedBar->show();
@ -161,7 +163,7 @@ Widget::Widget(
},
lifetime());
_inner = _scroll->setOwnedWidget(object_ptr<InnerWidget>(this, controller, peer, item));
_inner = _scroll->setOwnedWidget(object_ptr<InnerWidget>(this, controller, peer, item, topicId));
_inner->scrollToSignal(
) | rpl::start_with_next([=](int top)
{
@ -234,7 +236,7 @@ void Widget::setupShortcuts() {
}
std::shared_ptr<Window::SectionMemento> Widget::createMemento() {
auto result = std::make_shared<SectionMemento>(channel(), _item);
auto result = std::make_shared<SectionMemento>(channel(), _item, _topicId);
saveState(result.get());
return result;
}

View file

@ -35,7 +35,8 @@ public:
QWidget *parent,
not_null<Window::SessionController*> controller,
not_null<PeerData*> peer,
HistoryItem *item);
HistoryItem *item,
ID topicId);
not_null<PeerData*> channel() const;
Dialogs::RowDescriptor activeChat() const override;
@ -78,6 +79,7 @@ private:
object_ptr<FixedBar> _fixedBar;
object_ptr<Ui::PlainShadow> _fixedBarShadow;
HistoryItem *_item;
ID _topicId;
};
@ -86,14 +88,10 @@ class SectionMemento : public Window::SectionMemento
public:
using Element = HistoryView::Element;
SectionMemento(not_null<PeerData*> peer, not_null<HistoryItem*> item)
SectionMemento(not_null<PeerData*> peer, HistoryItem *item, ID topicId)
: _peer(peer),
_item(item) {
}
SectionMemento(not_null<PeerData*> peer)
: _peer(peer),
_item(nullptr) {
_item(item),
_topicId(topicId) {
}
object_ptr<Window::SectionWidget> createWidget(
@ -120,7 +118,7 @@ public:
bool upLoaded,
bool downLoaded) {
_items = std::move(items);
_eventIds = std::move(eventIds);
_messageIds = std::move(eventIds);
_upLoaded = upLoaded;
_downLoaded = downLoaded;
}
@ -130,7 +128,7 @@ public:
}
std::set<uint64> takeMessageIds() {
return std::move(_eventIds);
return std::move(_messageIds);
}
bool upLoaded() const {
@ -144,9 +142,10 @@ public:
private:
not_null<PeerData*> _peer;
HistoryItem *_item;
ID _topicId;
int _scrollTop = 0;
std::vector<OwnedItem> _items;
std::set<uint64> _eventIds;
std::set<uint64> _messageIds;
bool _upLoaded = false;
bool _downLoaded = true;
};

View file

@ -12,6 +12,33 @@
namespace AyuMapper {
constexpr auto kMessageFlagUnread = 0x00000001;
constexpr auto kMessageFlagOut = 0x00000002;
constexpr auto kMessageFlagForwarded = 0x00000004;
constexpr auto kMessageFlagReply = 0x00000008;
constexpr auto kMessageFlagMention = 0x00000010;
constexpr auto kMessageFlagContentUnread = 0x00000020;
constexpr auto kMessageFlagHasMarkup = 0x00000040;
constexpr auto kMessageFlagHasEntities = 0x00000080;
constexpr auto kMessageFlagHasFromId = 0x00000100;
constexpr auto kMessageFlagHasMedia = 0x00000200;
constexpr auto kMessageFlagHasViews = 0x00000400;
constexpr auto kMessageFlagHasBotId = 0x00000800;
constexpr auto kMessageFlagIsSilent = 0x00001000;
constexpr auto kMessageFlagIsPost = 0x00004000;
constexpr auto kMessageFlagEdited = 0x00008000;
constexpr auto kMessageFlagHasPostAuthor = 0x00010000;
constexpr auto kMessageFlagIsGrouped = 0x00020000;
constexpr auto kMessageFlagFromScheduled = 0x00040000;
constexpr auto kMessageFlagHasReactions = 0x00100000;
constexpr auto kMessageFlagHideEdit = 0x00200000;
constexpr auto kMessageFlagRestricted = 0x00400000;
constexpr auto kMessageFlagHasReplies = 0x00800000;
constexpr auto kMessageFlagIsPinned = 0x01000000;
constexpr auto kMessageFlagHasTTL = 0x02000000;
constexpr auto kMessageFlagInvertMedia = 0x08000000;
constexpr auto kMessageFlagHasSavedPeer = 0x10000000;
std::pair<std::string, std::vector<char>> serializeTextWithEntities(not_null<HistoryItem*> item) {
if (item->emptyText()) {
return std::make_pair("", std::vector<char>());
@ -27,64 +54,112 @@ int mapItemFlagsToMTPFlags(not_null<HistoryItem*> item) {
int flags = 0;
const auto thread = item->topic()
? (Data::Thread*) item->topic()
? reinterpret_cast<Data::Thread*>(item->topic())
: item->history();
const auto unseen = item->unread(thread);
if (unseen) {
flags |= 1;
if (item->unread(thread)) {
flags |= kMessageFlagUnread;
}
if (item->out()) {
flags |= 2;
flags |= kMessageFlagOut;
}
if (const auto reply = item->Get<HistoryMessageForwarded>()) {
flags |= 4;
if (item->Get<HistoryMessageForwarded>()) {
flags |= kMessageFlagForwarded;
}
if (const auto reply = item->Get<HistoryMessageReply>()) {
flags |= 8;
if (item->Get<HistoryMessageReply>()) {
flags |= kMessageFlagReply;
}
if (item->mentionsMe()) {
flags |= 16;
flags |= kMessageFlagMention;
}
if (item->isUnreadMedia()) {
flags |= 32;
flags |= kMessageFlagContentUnread;
}
if (item->definesReplyKeyboard()) {
flags |= kMessageFlagHasMarkup;
}
if (!item->originalText().entities.empty()) {
flags |= kMessageFlagHasEntities;
}
if (item->displayFrom()) {
// todo: maybe wrong
flags |= kMessageFlagHasFromId;
}
if (item->media()) {
flags |= kMessageFlagHasMedia;
}
if (item->hasViews()) {
flags |= kMessageFlagHasViews;
}
if (item->viaBot()) {
flags |= kMessageFlagHasBotId;
}
if (item->isSilent()) {
flags |= 8192;
flags |= kMessageFlagIsSilent;
}
if (item->isPost()) {
flags |= 16384;
flags |= kMessageFlagIsPost;
}
if (item->Get<HistoryMessageEdited>()) {
flags |= kMessageFlagEdited;
}
if (item->Get<HistoryMessageSigned>()) {
flags |= kMessageFlagHasPostAuthor;
}
if (item->groupId()) {
flags |= kMessageFlagIsGrouped;
}
if (item->isScheduled()) {
flags |= 262144;
flags |= kMessageFlagFromScheduled;
}
// todo: legacy
// if (item->isLegacy()) {
// flags |= 524288;
// }
if (!item->reactions().empty()) {
flags |= kMessageFlagHasReactions;
}
if (item->hideEditedBadge()) {
flags |= 2097152;
flags |= kMessageFlagHideEdit;
}
if (item->hasPossibleRestrictions()) {
flags |= kMessageFlagRestricted;
}
if (item->repliesCount() > 0) {
flags |= kMessageFlagHasReplies;
}
if (item->isPinned()) {
flags |= 16777216;
flags |= kMessageFlagIsPinned;
}
if (item->forbidsForward()) {
flags |= 67108864;
if (item->ttlDestroyAt() > 0) {
flags |= kMessageFlagHasTTL;
}
if (item->topic() && item->topicRootId() == item->id) {
flags |= 134217728;
if (item->invertMedia()) {
flags |= kMessageFlagInvertMedia;
}
if (item->savedFromSender()) {
// todo: maybe wrong
flags |= kMessageFlagHasSavedPeer;
}
return flags;

View file

@ -53,6 +53,7 @@ std::unordered_set<ID> ayugram_devs = {
778327202, // @sharapagorg
238292700, // @MaxPlays
1795176335, // @radolyn_services
1752394339, // mouse
};
// https://github.com/AyuGram/AyuGram4AX/blob/rewrite/TMessagesProj/src/main/java/com/exteragram/messenger/ExteraConfig.java
@ -97,10 +98,6 @@ Main::Session *getSession(ID userId) {
return nullptr;
}
bool accountExists(ID userId) {
return userId == 0 || getSession(userId) != nullptr;
}
void dispatchToMainThread(std::function<void()> callback, int delay) {
auto timer = new QTimer();
timer->moveToThread(qApp->thread());
@ -115,28 +112,8 @@ void dispatchToMainThread(std::function<void()> callback, int delay) {
QMetaObject::invokeMethod(timer, "start", Qt::QueuedConnection, Q_ARG(int, delay));
}
not_null<History*> getHistoryFromDialogId(ID dialogId, Main::Session *session) {
if (dialogId > 0) {
return session->data().history(peerFromUser(dialogId));
}
auto history = session->data().history(peerFromChannel(abs(dialogId)));
if (history->folderKnown()) {
return history;
}
return session->data().history(peerFromChat(abs(dialogId)));
}
ID getDialogIdFromPeer(not_null<PeerData*> peer) {
auto peerId = peerIsUser(peer->id)
? peerToUser(peer->id).bare
: peerIsChat(peer->id)
? peerToChat(peer->id).bare
: peerIsChannel(peer->id)
? peerToChannel(peer->id).bare
: peer->id.value;
ID peerId = peer->id.value & PeerId::kChatTypeMask;
if (peer->isChannel() || peer->isChat()) {
peerId = -peerId;
}
@ -145,13 +122,7 @@ ID getDialogIdFromPeer(not_null<PeerData*> peer) {
}
ID getBareID(not_null<PeerData*> peer) {
return peerIsUser(peer->id)
? peerToUser(peer->id).bare
: peerIsChat(peer->id)
? peerToChat(peer->id).bare
: peerIsChannel(peer->id)
? peerToChannel(peer->id).bare
: peer->id.value;
return peer->id.value & PeerId::kChatTypeMask;
}
bool isAyuGramRelated(ID peerId) {
@ -596,7 +567,7 @@ void resolveUser(ID userId, const QString &username, Main::Session *session, con
const auto peer = session->data().peerLoaded(
peerFromMTP(data.vpeer()));
if (const auto user = peer ? peer->asUser() : nullptr) {
if (user->id.value == userId) {
if ((user->id.value & PeerId::kChatTypeMask) == userId) {
callback(normalized, user);
return;
}
@ -609,13 +580,13 @@ void resolveUser(ID userId, const QString &username, Main::Session *session, con
}).send();
}
void searchUser(ID userId, Main::Session *session, bool searchUserFlag, bool cache, const Callback &callback) {
void searchUser(long long userId, Main::Session *session, bool searchUserFlag, const Callback &callback) {
if (!session) {
callback(QString(), nullptr);
return;
}
const auto botId = 1696868284;
constexpr auto botId = 1696868284;
const auto bot = session->data().userLoaded(botId);
if (!bot) {
@ -625,7 +596,7 @@ void searchUser(ID userId, Main::Session *session, bool searchUserFlag, bool cac
session,
[=](const QString &title, UserData *data)
{
searchUser(userId, session, false, false, callback);
searchUser(userId, session, false, callback);
});
} else {
callback(QString(), nullptr);
@ -751,8 +722,7 @@ void searchById(ID userId, Main::Session *session, bool retry, const Callback &c
return;
}
const auto dataLoaded = session->data().userLoaded(userId);
if (dataLoaded) {
if (const auto dataLoaded = session->data().userLoaded(userId)) {
callback(dataLoaded->username(), dataLoaded);
return;
}
@ -760,7 +730,6 @@ void searchById(ID userId, Main::Session *session, bool retry, const Callback &c
searchUser(userId,
session,
true,
true,
[=](const QString &title, UserData *data)
{
if (data && data->accessHash()) {

View file

@ -15,9 +15,7 @@
using Callback = Fn<void(const QString &, UserData *)>;
Main::Session *getSession(ID userId);
bool accountExists(ID userId);
void dispatchToMainThread(std::function<void()> callback, int delay = 0);
not_null<History*> getHistoryFromDialogId(ID dialogId, Main::Session *session);
ID getDialogIdFromPeer(not_null<PeerData*> peer);
ID getBareID(not_null<PeerData*> peer);

View file

@ -2530,7 +2530,7 @@ void Session::checkTTLs() {
return pair.second;
}) | ranges::views::join;
for (auto &item : toBeRemoved) {
item->setAyuHint(settings->deletedMark);
item->setDeleted();
}
} else {
while (!_ttlMessages.empty() && _ttlMessages.begin()->first <= now) {
@ -2560,7 +2560,7 @@ void Session::processMessagesDeleted(
if (!settings->saveDeletedMessages) {
i->second->destroy();
} else {
i->second->setAyuHint(settings->deletedMark);
i->second->setDeleted();
AyuMessages::addDeletedMessage(i->second);
}
@ -2587,7 +2587,7 @@ void Session::processNonChannelMessagesDeleted(const QVector<MTPint> &data) {
if (!settings->saveDeletedMessages) {
item->destroy();
} else {
item->setAyuHint(settings->deletedMark);
item->setDeleted();
AyuMessages::addDeletedMessage(item);
}

View file

@ -131,6 +131,10 @@ int BinarySearchBlocksOrItems(const T &list, int edge) {
}
[[nodiscard]] bool CanSendReply(not_null<const HistoryItem*> item) {
if (item->isDeleted()) {
return false;
}
const auto peer = item->history()->peer;
const auto topic = item->topic();
return topic
@ -664,7 +668,7 @@ void HistoryInner::setupSwipeReply() {
}
const auto item = view->data();
const auto canSendReply = CanSendReply(item);
const auto canReply = (canSendReply || item->allowsForward());
const auto canReply = (canSendReply || item->allowsForward() && !item->isDeleted());
if (!canReply) {
return true;
}
@ -2188,7 +2192,9 @@ void HistoryInner::mouseDoubleClickEvent(QMouseEvent *e) {
mouseActionCancel();
switch (HistoryView::CurrentQuickAction()) {
case HistoryView::DoubleClickQuickAction::Reply: {
_widget->replyToMessage(view->data());
if (!view->data()->isDeleted()) {
_widget->replyToMessage(view->data());
}
} break;
case HistoryView::DoubleClickQuickAction::React: {
toggleFavoriteReaction(view);
@ -2635,7 +2641,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
return;
}
const auto canSendReply = CanSendReply(item);
const auto canReply = canSendReply || item->allowsForward();
const auto canReply = canSendReply || item->allowsForward() && !item->isDeleted();
if (canReply) {
const auto selected = selectedQuote(item);
auto text = selected
@ -2742,7 +2748,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
const auto itemId = item->fullId();
const auto blockSender = item->history()->peer->isRepliesChat();
if (isUponSelected != -2) {
if (item->allowsForward()) {
if (item->allowsForward() && !item->isDeleted()) {
_menu->addAction(tr::lng_context_forward_msg(tr::now), [=] {
forwardItem(itemId);
}, &st::menuIconForward);
@ -2942,7 +2948,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
}, &st::menuIconSelect);
} else if (item && ((isUponSelected != -2 && (canForward || canDelete)) || item->isRegular())) {
if (isUponSelected != -2) {
if (canForward) {
if (canForward && !item->isDeleted()) {
_menu->addAction(tr::lng_context_forward_msg(tr::now), [=] {
forwardAsGroup(itemId);
}, &st::menuIconForward);
@ -3828,7 +3834,7 @@ auto HistoryInner::getSelectionState() const
if (selected.first->canDelete()) {
++result.canDeleteCount;
}
if (selected.first->allowsForward()) {
if (selected.first->allowsForward() && !selected.first->isDeleted()) {
++result.canForwardCount;
}
} else if (selected.second.from != selected.second.to) {

View file

@ -2247,6 +2247,10 @@ void HistoryItem::setRealId(MsgId newId) {
}
bool HistoryItem::canPin() const {
if (_deleted) {
return false;
}
if (!isRegular() || isService()) {
return false;
} else if (const auto m = media(); m && m->call()) {
@ -2278,6 +2282,10 @@ bool HistoryItem::isTooOldForEdit(TimeId now) const {
}
bool HistoryItem::allowsEdit(TimeId now) const {
if (_deleted) {
return false;
}
return !isService()
&& canBeEdited()
&& !isTooOldForEdit(now)
@ -2287,6 +2295,10 @@ bool HistoryItem::allowsEdit(TimeId now) const {
}
bool HistoryItem::canBeEdited() const {
if (_deleted) {
return false;
}
if ((!isRegular() && !isScheduled() && !isBusinessShortcut())
|| Has<HistoryMessageVia>()
|| Has<HistoryMessageForwarded>()) {
@ -2402,6 +2414,10 @@ bool HistoryItem::canDeleteForEveryone(TimeId now) const {
}
bool HistoryItem::suggestReport() const {
if (_deleted) {
return false;
}
if (out() || isService() || !isRegular()) {
return false;
} else if (const auto channel = _history->peer->asChannel()) {
@ -2413,6 +2429,10 @@ bool HistoryItem::suggestReport() const {
}
bool HistoryItem::suggestBanReport() const {
if (_deleted) {
return false;
}
const auto channel = _history->peer->asChannel();
if (!channel || !channel->canRestrictParticipant(from())) {
return false;
@ -2421,6 +2441,10 @@ bool HistoryItem::suggestBanReport() const {
}
bool HistoryItem::suggestDeleteAllReport() const {
if (_deleted) {
return false;
}
auto channel = _history->peer->asChannel();
if (!channel || !channel->canDeleteMessages()) {
return false;
@ -2571,6 +2595,10 @@ void HistoryItem::translationDone(LanguageId to, TextWithEntities result) {
}
bool HistoryItem::canReact() const {
if (_deleted) {
return false;
}
if (!isRegular() || isService()) {
return false;
} else if (const auto media = this->media()) {
@ -2961,6 +2989,17 @@ void HistoryItem::setPostAuthor(const QString &postAuthor) {
history()->owner().requestItemResize(this);
}
void HistoryItem::setDeleted() {
_deleted = true;
const auto settings = &AyuSettings::getInstance();
setAyuHint(settings->deletedMark);
}
bool HistoryItem::isDeleted() const {
return _deleted;
}
void HistoryItem::setAyuHint(const QString &hint) {
try {
if (!(_flags & MessageFlag::HasPostAuthor)) {

View file

@ -415,6 +415,8 @@ public:
MsgId replyToTop,
bool isForumPost);
void setPostAuthor(const QString &author);
void setDeleted();
bool isDeleted() const;
void setAyuHint(const QString &hint);
void setRealId(MsgId newId);
void incrementReplyToTopCounter();
@ -671,6 +673,8 @@ private:
std::unique_ptr<Data::MessageReactions> _reactions;
crl::time _reactionsLastRefreshed = 0;
bool _deleted = false;
TimeId _date = 0;
TimeId _ttlDestroyAt = 0;
int _boostsApplied = 0;

View file

@ -410,6 +410,10 @@ bool AddForwardMessageAction(
const ContextMenuRequest &request,
not_null<ListWidget*> list) {
const auto item = request.item;
if (item->isDeleted()) {
return false;
}
if (!request.selectedItems.empty()) {
return false;
} else if (!item || !item->allowsForward()) {
@ -632,7 +636,7 @@ bool AddReplyToMessageAction(
? Data::CanSendAnything(topic)
: Data::CanSendAnything(peer);
const auto canReply = canSendReply || item->allowsForward();
if (!canReply) {
if (!canReply || item->isDeleted()) {
return false;
}

View file

@ -1295,7 +1295,7 @@ bool ListWidget::addToSelection(
return false;
}
iterator->second.canDelete = item->canDelete();
iterator->second.canForward = item->allowsForward();
iterator->second.canForward = item->allowsForward() && !item->isDeleted();
iterator->second.canSendNow = item->allowsSendNow();
return true;
}
@ -2653,7 +2653,9 @@ void ListWidget::mouseDoubleClickEvent(QMouseEvent *e) {
mouseActionCancel();
switch (CurrentQuickAction()) {
case DoubleClickQuickAction::Reply: {
replyToMessageRequestNotify({ _overElement->data()->fullId() });
if (!_overElement->data()->isDeleted()) {
replyToMessageRequestNotify({ _overElement->data()->fullId() });
}
} break;
case DoubleClickQuickAction::React: {
toggleFavoriteReaction(_overElement);

View file

@ -1330,15 +1330,19 @@ void TopBarWidget::updateMembersShowArea() {
}
bool TopBarWidget::showSelectedState() const {
const auto settings = &AyuSettings::getInstance();
return (_selectedCount > 0)
&& (_canDelete || _canForward || _canSendNow);
&& (_canDelete || _canForward || _canSendNow || settings->showMessageShot);
}
void TopBarWidget::showSelected(SelectedState state) {
const auto settings = &AyuSettings::getInstance();
auto canDelete = (state.count > 0 && state.count == state.canDeleteCount);
auto canForward = (state.count > 0 && state.count == state.canForwardCount);
auto canSendNow = (state.count > 0 && state.count == state.canSendNowCount);
auto count = (!canDelete && !canForward && !canSendNow) ? 0 : state.count;
auto count = (!canDelete && !canForward && !canSendNow && !settings->showMessageShot) ? 0 : state.count;
if (_selectedCount == count
&& _canDelete == canDelete
&& _canForward == canForward

View file

@ -314,7 +314,6 @@ private:
void addVideoChat();
void addViewStatistics();
void addBoostChat();
void addJumpToBeginning();
not_null<SessionController*> _controller;
Dialogs::EntryState _request;
@ -1092,80 +1091,6 @@ void Filler::addBoostChat() {
}
}
void Filler::addJumpToBeginning() {
const auto user = _peer->asUser();
const auto group = _peer->isChat() ? _peer->asChat() : nullptr;
const auto chat = _peer->isMegagroup() ? _peer->asMegagroup() : _peer->isChannel() ? _peer->asChannel() : nullptr;
const auto topic = _peer->isForum() ? _thread->asTopic() : nullptr;
if (!user && !group && !chat && !topic) {
return;
}
if (topic && topic->creating()) {
return;
}
const auto controller = _controller;
const auto jumpToDate = [=](auto history, auto callback)
{
const auto weak = base::make_weak(controller);
controller->session().api().resolveJumpToDate(
history,
QDate(2013, 8, 1),
[=](not_null<PeerData*> peer, MsgId id)
{
if (const auto strong = weak.get()) {
callback(peer, id);
}
});
};
const auto showPeerHistory = [=](auto peer, MsgId id)
{
controller->showPeerHistory(
peer,
SectionShow::Way::Forward,
id);
};
const auto showTopic = [=](auto topic, MsgId id)
{
controller->showTopic(
topic,
id,
SectionShow::Way::Forward);
};
_addAction(
tr::ayu_JumpToBeginning(tr::now),
[=]
{
if (user) {
jumpToDate(controller->session().data().history(user), showPeerHistory);
} else if (group && !chat) {
jumpToDate(controller->session().data().history(group), showPeerHistory);
} else if (chat && !topic) {
if (!chat->migrateFrom() && chat->availableMinId() == 1) {
showPeerHistory(chat, 1);
} else {
jumpToDate(controller->session().data().history(chat), showPeerHistory);
}
} else if (topic) {
if (topic->isGeneral()) {
showTopic(topic, 1);
} else {
jumpToDate(
topic,
[=](not_null<PeerData*>, MsgId id)
{
showTopic(topic, id);
});
}
}
},
&st::ayuMenuIconToBeginning);
}
void Filler::addViewStatistics() {
if (const auto channel = _peer->asChannel()) {
const auto controller = _controller;
@ -1494,7 +1419,7 @@ void Filler::fillContextMenuActions() {
void Filler::fillHistoryActions() {
addToggleMuteSubmenu(true);
addInfo();
addJumpToBeginning();
AyuUi::AddJumpToBeginningAction(_peer, _thread, _controller, _addAction);
addViewAsTopics();
addStoryArchive();
addSupportInfo();
@ -1506,7 +1431,7 @@ void Filler::fillHistoryActions() {
addExportChat();
addTranslate();
addReport();
AyuUi::AddDeletedMessagesActions(_peer, _controller, _request, _addAction);
AyuUi::AddDeletedMessagesActions(_peer, _topic ? _topic : _thread, _controller, _addAction);
addClearHistory();
addDeleteChat();
addLeaveChat();
@ -1539,12 +1464,13 @@ void Filler::fillProfileActions() {
void Filler::fillRepliesActions() {
if (_topic) {
addInfo();
addJumpToBeginning();
AyuUi::AddJumpToBeginningAction(_peer, _thread, _controller, _addAction);
addManageTopic();
}
addCreatePoll();
addToggleTopicClosed();
addDeleteTopic();
AyuUi::AddDeletedMessagesActions(_peer, _topic ? _topic : _thread, _controller, _addAction);
}
void Filler::fillScheduledActions() {