From 78c5dd9a8648dba7ca09f59b4b7460610c6ff3a6 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Mon, 18 Sep 2023 18:14:53 +0300 Subject: Telegram: ability to add custom chat reactions using NewHistory --- protocols/Telegram/res/reaction.ico | Bin 0 -> 1150 bytes protocols/Telegram/res/resource.rc | 21 ++++++++++ protocols/Telegram/src/main.cpp | 3 +- protocols/Telegram/src/menus.cpp | 75 +++++++++++++++++++++++++++++++++--- protocols/Telegram/src/proto.h | 10 ++++- protocols/Telegram/src/resource.h | 5 ++- protocols/Telegram/src/server.cpp | 35 +++++++++++++++++ 7 files changed, 141 insertions(+), 8 deletions(-) create mode 100644 protocols/Telegram/res/reaction.ico (limited to 'protocols/Telegram') diff --git a/protocols/Telegram/res/reaction.ico b/protocols/Telegram/res/reaction.ico new file mode 100644 index 0000000000..9fa0abcfc6 Binary files /dev/null and b/protocols/Telegram/res/reaction.ico differ diff --git a/protocols/Telegram/res/resource.rc b/protocols/Telegram/res/resource.rc index 340d24eb87..cf5e73e2f5 100644 --- a/protocols/Telegram/res/resource.rc +++ b/protocols/Telegram/res/resource.rc @@ -140,6 +140,16 @@ BEGIN PUSHBUTTON "Cancel",IDCANCEL,158,248,50,14 END +IDD_REACTIONS DIALOGEX 0, 0, 215, 40 +STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Forward message" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + COMBOBOX IDC_REACTIONS,8,4,201,12,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "OK",IDOK,104,22,50,14 + PUSHBUTTON "Cancel",IDCANCEL,158,22,50,14 +END + ///////////////////////////////////////////////////////////////////////////// // @@ -154,6 +164,7 @@ IDI_PREMIUM ICON "premium.ico" IDI_FORWARD ICON "forward.ico" +IDI_REACTION ICON "reaction.ico" ///////////////////////////////////////////////////////////////////////////// // @@ -180,6 +191,11 @@ BEGIN BEGIN BOTTOMMARGIN, 262 END + + "IDC_REACTION", DIALOG + BEGIN + BOTTOMMARGIN, 36 + END END #endif // APSTUDIO_INVOKED @@ -209,6 +225,11 @@ BEGIN 0 END +IDC_REACTION AFX_DIALOG_LAYOUT +BEGIN + 0 +END + #endif // English (Neutral) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/protocols/Telegram/src/main.cpp b/protocols/Telegram/src/main.cpp index 32206a9b6c..ee1aa1ecee 100644 --- a/protocols/Telegram/src/main.cpp +++ b/protocols/Telegram/src/main.cpp @@ -41,7 +41,8 @@ extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_PROTOC static IconItem iconList[] = { { LPGEN("Telegram Premium user"), "premuim", IDI_PREMIUM }, - { LPGEN("Forward"), "forward", IDI_FORWARD }, + { LPGEN("Forward"), "forward", IDI_FORWARD }, + { LPGEN("Reaction"), "reaction", IDI_REACTION }, }; int CMPlugin::Load() diff --git a/protocols/Telegram/src/menus.cpp b/protocols/Telegram/src/menus.cpp index 12bcdd2afa..73327f1665 100644 --- a/protocols/Telegram/src/menus.cpp +++ b/protocols/Telegram/src/menus.cpp @@ -35,15 +35,30 @@ void CTelegramProto::InitMenus() mi.hIcolibItem = g_plugin.getIconHandle(IDI_FORWARD); mi.name.a = LPGEN("Forward"); hmiForward = Menu_AddNewStoryMenuItem(&mi, 1); + + mi.position = 1000000; + mi.hIcolibItem = g_plugin.getIconHandle(IDI_REACTION); + mi.name.a = LPGEN("Reaction"); + hmiReaction = Menu_AddNewStoryMenuItem(&mi, 2); } int CTelegramProto::OnPrebuildMenu(WPARAM hContact, LPARAM) { - Menu_ShowItem(hmiForward, Proto_IsProtoOnContact(hContact, m_szModuleName)); + if (!Proto_IsProtoOnContact(hContact, m_szModuleName)) { + Menu_ShowItem(hmiForward, false); + Menu_ShowItem(hmiReaction, false); + } + else { + Menu_ShowItem(hmiForward, true); + + auto *pUser = FindUser(GetId(hContact)); + Menu_ShowItem(hmiReaction, pUser && pUser->pReactions); + } return 0; } ///////////////////////////////////////////////////////////////////////////////////////// +// Dialog for message forwarding class CForwardDlg : public CTelegramDlgBase { @@ -114,13 +129,63 @@ public: } }; +///////////////////////////////////////////////////////////////////////////////////////// +// Dialog for sending reaction + +class CReactionsDlg : public CTelegramDlgBase +{ + MEVENT m_hEvent; + TG_USER *m_pUser; + CCtrlCombo cmbReactions; + +public: + CReactionsDlg(CTelegramProto *ppro, MEVENT hEvent) : + CTelegramDlgBase(ppro, IDD_REACTIONS), + m_hEvent(hEvent), + cmbReactions(this, IDC_REACTIONS) + { + m_pUser = ppro->FindUser(ppro->GetId(db_event_getContact(hEvent))); + } + + bool OnInitDialog() override + { + for (auto &it : *m_pUser->pReactions) + cmbReactions.AddString(Utf2T(it), (LPARAM)it); + return true; + } + + bool OnApply() override + { + DB::EventInfo dbei(m_hEvent, false); + __int64 msgId = (dbei && dbei.szId) ? _atoi64(dbei.szId) : 0; + + char *pszEmoji = (char *)cmbReactions.GetCurData(); + auto reaction = TD::make_object(pszEmoji); + + m_proto->SendQuery(new TD::addMessageReaction(m_pUser->chatId, msgId, std::move(reaction), false, false)); + return true; + } +}; + +///////////////////////////////////////////////////////////////////////////////////////// +// Module entry point + INT_PTR CTelegramProto::SvcExecMenu(WPARAM iCommand, LPARAM pHandle) { switch (iCommand) { - case 1: - std::vector ids = NS_GetSelection(HANDLE(pHandle)); - if (!ids.empty()) - CForwardDlg(this, ids).DoModal(); + case 1: // forward message + { std::vector ids = NS_GetSelection(HANDLE(pHandle)); + if (!ids.empty()) + CForwardDlg(this, ids).DoModal(); + } + break; + + case 2: // reactions + { + MEVENT hCurrentEvent = NS_GetCurrent((HANDLE)pHandle); + if (hCurrentEvent != -1) + CReactionsDlg(this, hCurrentEvent).DoModal(); + } break; } return 0; diff --git a/protocols/Telegram/src/proto.h b/protocols/Telegram/src/proto.h index 27394a241c..a4bfc440d2 100644 --- a/protocols/Telegram/src/proto.h +++ b/protocols/Telegram/src/proto.h @@ -95,6 +95,11 @@ struct TG_USER : public MZeroedObject chatId = (isGroupChat) ? -1 : id; } + ~TG_USER() + { + delete pReactions; + } + int64_t id, chatId; MCONTACT hContact; bool isGroupChat, bLoadMembers; @@ -103,6 +108,7 @@ struct TG_USER : public MZeroedObject time_t m_timer1 = 0, m_timer2 = 0; SESSION_INFO *m_si = nullptr; TD::chatNotificationSettings notificationSettings; + OBJLIST *pReactions = nullptr; CMStringW getDisplayName() const; }; @@ -145,6 +151,7 @@ struct TG_OWN_MESSAGE class CTelegramProto : public PROTO { friend class CForwardDlg; + friend class CReactionsDlg; friend class CAddPhoneContactDlg; class CProtoImpl @@ -236,6 +243,7 @@ class CTelegramProto : public PROTO void ProcessChatLastMessage(TD::updateChatLastMessage *pObj); void ProcessChatNotification(TD::updateChatNotificationSettings *pObj); void ProcessChatPosition(TD::updateChatPosition *pObj); + void ProcessChatReactions(TD::updateChatAvailableReactions *); void ProcessConnectionState(TD::updateConnectionState *pObj); void ProcessDeleteMessage(TD::updateDeleteMessages *pObj); void ProcessFile(TD::updateFile *pObj); @@ -302,7 +310,7 @@ class CTelegramProto : public PROTO MCONTACT GetRealContact(const TG_USER *pUser); // Menus - HGENMENU hmiForward; + HGENMENU hmiForward, hmiReaction; void InitMenus(); diff --git a/protocols/Telegram/src/resource.h b/protocols/Telegram/src/resource.h index f72710ca00..6a15eac64e 100644 --- a/protocols/Telegram/src/resource.h +++ b/protocols/Telegram/src/resource.h @@ -10,6 +10,8 @@ #define IDI_FORWARD 105 #define IDD_FORWARD 106 #define IDD_ADD_PHONE 107 +#define IDI_REACTION 108 +#define IDD_REACTIONS 109 #define IDC_PHONE 1001 #define IDC_DEFGROUP 1002 #define IDC_HIDECHATS 1003 @@ -29,6 +31,7 @@ #define IDC_LAST_NAME 1015 #define IDC_CLIST 1016 #define IDC_COMPRESS_FILES 1017 +#define IDC_REACTIONS 1018 // Next default values for new objects // @@ -36,7 +39,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 109 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1016 +#define _APS_NEXT_CONTROL_VALUE 1019 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/protocols/Telegram/src/server.cpp b/protocols/Telegram/src/server.cpp index 3eb42bd103..403d2f390c 100644 --- a/protocols/Telegram/src/server.cpp +++ b/protocols/Telegram/src/server.cpp @@ -161,6 +161,10 @@ void CTelegramProto::ProcessResponse(td::ClientManager::Response response) ProcessChatPosition((TD::updateChatPosition *)response.object.get()); break; + case TD::updateChatAvailableReactions::ID: + ProcessChatReactions((TD::updateChatAvailableReactions *)response.object.get()); + break; + case TD::updateChatReadInbox::ID: ProcessMarkRead((TD::updateChatReadInbox *)response.object.get()); break; @@ -516,6 +520,37 @@ void CTelegramProto::ProcessChatPosition(TD::updateChatPosition *pObj) } } +void CTelegramProto::ProcessChatReactions(TD::updateChatAvailableReactions *pObj) +{ + if (pObj->available_reactions_->get_id() != TD::chatAvailableReactionsSome::ID) { + debugLogA("Unsupported reactions type: %d", pObj->available_reactions_->get_id()); + return; + } + + auto &pReactions = ((TD::chatAvailableReactionsSome *)pObj->available_reactions_.get())->reactions_; + + if (auto *pChat = FindChat(pObj->chat_id_)) { + if (!pChat->pReactions) + pChat->pReactions = new OBJLIST(1); + else + pChat->pReactions->destroy(); + + for (auto &it : pReactions) { + if (it->get_id() != TD::reactionTypeEmoji::ID) + continue; + + auto *pEmoji = (TD::reactionTypeEmoji *)it.get(); + auto &str = pEmoji->emoji_; + pChat->pReactions->insert(mir_strcpy(new char[str.length() + 1], str.c_str())); + } + + if (pChat->pReactions->getCount() == 0) { + delete pChat->pReactions; + pChat->pReactions = nullptr; + } + } +} + void CTelegramProto::ProcessConnectionState(TD::updateConnectionState *pObj) { pConnState = std::move(pObj->state_); -- cgit v1.2.3