From a5e0afb7313249e5da0414ae54a64b18bb59f6ca Mon Sep 17 00:00:00 2001 From: iProgramInCpp Date: Fri, 31 May 2024 10:31:52 +0300 Subject: [PATCH] * Refactor pinned message list. * Pin list: Fix repaint bug where avatars, attachments and custom emoji weren't updated when loaded. --- src/windows/Frontend_Win32.cpp | 6 +- src/windows/GuildHeader.cpp | 4 +- src/windows/Main.cpp | 6 +- src/windows/PinList.cpp | 179 ++++++++++++++++++++++++++++ src/windows/PinList.hpp | 40 +++++++ src/windows/PinnedMessageViewer.cpp | 166 -------------------------- src/windows/PinnedMessageViewer.hpp | 16 --- vs/DiscordMessenger.vcxproj | 4 +- 8 files changed, 230 insertions(+), 191 deletions(-) create mode 100644 src/windows/PinList.cpp create mode 100644 src/windows/PinList.hpp delete mode 100644 src/windows/PinnedMessageViewer.cpp delete mode 100644 src/windows/PinnedMessageViewer.hpp diff --git a/src/windows/Frontend_Win32.cpp b/src/windows/Frontend_Win32.cpp index d528e03..ca4ae22 100644 --- a/src/windows/Frontend_Win32.cpp +++ b/src/windows/Frontend_Win32.cpp @@ -4,7 +4,7 @@ #include "ImageLoader.hpp" #include "ProfilePopout.hpp" #include "QRCodeDialog.hpp" -#include "PinnedMessageViewer.hpp" +#include "PinList.hpp" #include "../discord/UpdateChecker.hpp" #include "../discord/LocalSettings.hpp" @@ -130,8 +130,8 @@ void Frontend_Win32::OnRequestDone(NetRequest* pRequest) void Frontend_Win32::OnLoadedPins(Snowflake channel, const std::string& data) { - if (PmvIsActive()) - PmvOnLoadedPins(channel, data); + if (PinList::IsActive()) + PinList::OnLoadedPins(channel, data); } void Frontend_Win32::OnUpdateAvailable(const std::string& url, const std::string& version) diff --git a/src/windows/GuildHeader.cpp b/src/windows/GuildHeader.cpp index a8ce1d9..388a5ba 100644 --- a/src/windows/GuildHeader.cpp +++ b/src/windows/GuildHeader.cpp @@ -1,5 +1,5 @@ #include "GuildHeader.hpp" -#include "PinnedMessageViewer.hpp" +#include "PinList.hpp" #define GUILD_HEADER_COLOR COLOR_ACTIVECAPTION #define GUILD_HEADER_COLOR_2 COLOR_GRADIENTACTIVECAPTION @@ -515,7 +515,7 @@ LRESULT CALLBACK GuildHeader::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA pThis->m_buttons[lParam].m_rect.bottom }; ClientToScreen(hWnd, &pt); - PmvCreate(pChan->m_snowflake, pGuild->m_snowflake, pt.x, pt.y, true); + PinList::Show(pChan->m_snowflake, pGuild->m_snowflake, pt.x, pt.y, true); break; } case IDTB_MEMBERS: diff --git a/src/windows/Main.cpp b/src/windows/Main.cpp index f379834..1d33adf 100644 --- a/src/windows/Main.cpp +++ b/src/windows/Main.cpp @@ -13,7 +13,7 @@ #include "ImageLoader.hpp" #include "ProfilePopout.hpp" #include "ImageViewer.hpp" -#include "PinnedMessageViewer.hpp" +#include "PinList.hpp" #include "MemberList.hpp" #include "LogonDialog.hpp" #include "QRCodeDialog.hpp" @@ -609,6 +609,7 @@ LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { Snowflake sf = *(Snowflake*) lParam; g_pMessageList->OnUpdateEmoji(sf); + PinList::OnUpdateEmoji(sf); break; } case WM_UPDATEUSER: @@ -617,6 +618,7 @@ LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) g_pMessageList->OnUpdateAvatar(sf); g_pMemberList->OnUpdateAvatar(sf); g_pChannelView->OnUpdateAvatar(sf); + PinList::OnUpdateAvatar(sf); if (ProfilePopout::GetUser() == sf) ProfilePopout::Update(); @@ -649,7 +651,7 @@ LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { ImagePlace pl = *(ImagePlace*)lParam; g_pMessageList->OnUpdateEmbed(pl.key); - + PinList::OnUpdateEmbed(pl.key); break; } case WM_REPAINTPROFILE: diff --git a/src/windows/PinList.cpp b/src/windows/PinList.cpp new file mode 100644 index 0000000..b4d3750 --- /dev/null +++ b/src/windows/PinList.cpp @@ -0,0 +1,179 @@ +#include +#include "PinList.hpp" +#include "MessageList.hpp" + +#define DM_PINNED_MESSAGES_CLASS TEXT("DMPinnedMessageListClass"); + +Snowflake PinList::m_channel, PinList::m_guild; +MessageList* PinList::m_pMessageList; +PinnedMap PinList::m_map; +POINT PinList::m_appearXY; +bool PinList::m_bRightJustify; +bool PinList::m_bActive; + +bool PinList::IsActive() +{ + return m_bActive; +} + +void PinList::AddMessage(Snowflake channelID, const Message& msg) +{ + m_map[channelID].push_back(msg); + + if (m_channel == channelID && m_pMessageList) + m_pMessageList->AddMessage(msg); +} + +void PinList::Initialize(HWND hWnd) +{ + Channel* pChan = GetDiscordInstance()->GetChannelGlobally(m_channel); + if (!pChan) { + EndDialog(hWnd, 0); + return; + } + + char buff[4096]; + snprintf(buff, _countof(buff), TmGetString(IDS_PINNED_MESSAGES_IN).c_str(), pChan->m_name.c_str()); + TCHAR* tchr = ConvertCppStringToTString(buff); + SetWindowText(hWnd, tchr); + free(tchr); + + // Move the window + RECT rect{}; + GetWindowRect(hWnd, &rect); + int width = rect.right - rect.left; + int height = rect.bottom - rect.top; + int xPos = m_appearXY.x; + int yPos = m_appearXY.y; + if (m_bRightJustify) { + xPos -= width; + } + MoveWindow(hWnd, xPos, yPos, width, height, false); + + HWND child = GetDlgItem(hWnd, IDC_MESSAGE_LIST); + + GetWindowRect(child, &rect); + ScreenToClientRect(hWnd, &rect); + DestroyWindow(child); + + SAFE_DELETE(m_pMessageList); + + if (m_map[m_channel].empty()) { + Message msg; + msg.m_type = MessageType::LOADING_PINNED_MESSAGES; + msg.m_author = TmGetString(IDS_PLEASE_WAIT); + msg.m_snowflake = 1; + AddMessage(m_channel, msg); + + GetDiscordInstance()->RequestPinnedMessages(m_channel); + } + + m_pMessageList = MessageList::Create(hWnd, &rect); + m_pMessageList->SetManagedByOwner(true); + m_pMessageList->SetTopDown(true); + m_pMessageList->SetGuild(m_guild); + m_pMessageList->SetChannel(m_channel); + + for (auto& msg : m_map[m_channel]) + m_pMessageList->AddMessage(msg); + + m_bActive = true; +} + +void PinList::OnLoadedPins(Snowflake channelID, const std::string& data) +{ + nlohmann::json j = nlohmann::json::parse(data); + + if (!j.is_array()) { + assert(!"uh oh"); + return; + } + + m_map[m_channel].clear(); + if (m_channel == channelID) + m_pMessageList->ClearMessages(); + + if (j.empty()) { + Message msg; + msg.m_author = " "; + msg.m_type = MessageType::NO_PINNED_MESSAGES; + msg.m_anchor = 1; + msg.m_snowflake = 1; + AddMessage(channelID, msg); + } + else + { + for (auto& msgo : j) + { + Message msg; + msg.Load(msgo, m_guild); + msg.m_anchor = 1; + AddMessage(channelID, msg); + } + } + + // HACK + m_pMessageList->Repaint(); +} + +void PinList::OnUpdateEmbed(const std::string& key) +{ + if (m_pMessageList) + m_pMessageList->OnUpdateEmbed(key); +} + +void PinList::OnUpdateAvatar(Snowflake key) +{ + if (m_pMessageList) + m_pMessageList->OnUpdateAvatar(key); +} + +void PinList::OnUpdateEmoji(Snowflake key) +{ + if (m_pMessageList) + m_pMessageList->OnUpdateEmoji(key); +} + +void PinList::OnClickMessage(Snowflake sf) +{ + GetDiscordInstance()->JumpToMessage(m_guild, m_channel, sf); +} + +BOOL CALLBACK PinList::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_INITDIALOG: + Initialize(hWnd); + return TRUE; + + case WM_COMMAND: + if (wParam == IDCANCEL) { + EndDialog(hWnd, 0); + return TRUE; + } + break; + + case WM_CLICKEDMESSAGE: + EndDialog(hWnd, 0); + OnClickMessage(*(Snowflake*) lParam); + return TRUE; + + case WM_DESTROY: + SAFE_DELETE(m_pMessageList); + m_bActive = false; + break; + } + + return FALSE; +} + +void PinList::Show(Snowflake channelID, Snowflake guildID, int x, int y, bool rightJustify) +{ + m_channel = channelID; + m_guild = guildID; + m_appearXY = { x, y }; + m_bRightJustify = rightJustify; + + DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_DIALOG_PINNEDMESSAGES), g_Hwnd, &DlgProc); +} diff --git a/src/windows/PinList.hpp b/src/windows/PinList.hpp new file mode 100644 index 0000000..52c45c2 --- /dev/null +++ b/src/windows/PinList.hpp @@ -0,0 +1,40 @@ +#pragma once +#define WIN32_LEAN_AND_MEAN +#include +#include +#include "../discord/Snowflake.hpp" +#include "../discord/Message.hpp" + +// GET Request: discordapi/channels/$CHANNEL_ID/pins +// RESPONSE: Array of message objects + +class MessageList; + +typedef std::map > PinnedMap; + +class PinList +{ +public: + static void Initialize(HWND hWnd); + static void OnLoadedPins(Snowflake channelID, const std::string& data); + static void OnUpdateEmbed(const std::string& key); + static void OnUpdateAvatar(Snowflake key); + static void OnUpdateEmoji(Snowflake key); + static bool IsActive(); + static void Show(Snowflake channelID, Snowflake guildID, int x, int y, bool rightJustify = false); + +protected: + friend class MessageList; + static void OnClickMessage(Snowflake sf); + +private: + static void AddMessage(Snowflake channelID, const Message& msg); + static BOOL CALLBACK DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + +private: + static Snowflake m_channel, m_guild; + static MessageList* m_pMessageList; + static PinnedMap m_map; + static POINT m_appearXY; + static bool m_bActive, m_bRightJustify; +}; diff --git a/src/windows/PinnedMessageViewer.cpp b/src/windows/PinnedMessageViewer.cpp deleted file mode 100644 index 6c501ae..0000000 --- a/src/windows/PinnedMessageViewer.cpp +++ /dev/null @@ -1,166 +0,0 @@ -#include -#include "PinnedMessageViewer.hpp" -#include "MessageList.hpp" - -#define DM_PINNED_MESSAGES_CLASS TEXT("DMPinnedMessageListClass"); - -static Snowflake g_channel, g_guild; -static POINT g_appearXY; -static bool g_rightJustify; -static MessageList* g_pPmvMessageList; -static std::map > g_pinnedMessageMap; -static bool g_bActive; - -bool PmvIsActive() -{ - return g_bActive; -} - -void PmvAddMessage(Snowflake channelID, const Message& msg) -{ - g_pinnedMessageMap[channelID].push_back(msg); - - if (g_channel == channelID && g_pPmvMessageList) - g_pPmvMessageList->AddMessage(msg); -} - -void PmvInitialize(HWND hWnd) -{ - Channel* pChan = GetDiscordInstance()->GetChannelGlobally(g_channel); - if (!pChan) { - EndDialog(hWnd, 0); - return; - } - - char buff[4096]; - snprintf(buff, _countof(buff), TmGetString(IDS_PINNED_MESSAGES_IN).c_str(), pChan->m_name.c_str()); - TCHAR* tchr = ConvertCppStringToTString(buff); - SetWindowText(hWnd, tchr); - free(tchr); - - // Move the window - RECT rect{}; - GetWindowRect(hWnd, &rect); - int width = rect.right - rect.left; - int height = rect.bottom - rect.top; - int xPos = g_appearXY.x; - int yPos = g_appearXY.y; - if (g_rightJustify) { - xPos -= width; - } - MoveWindow(hWnd, xPos, yPos, width, height, false); - - HWND child = GetDlgItem(hWnd, IDC_MESSAGE_LIST); - - GetWindowRect(child, &rect); - ScreenToClientRect(hWnd, &rect); - DestroyWindow(child); - - if (g_pPmvMessageList) - delete g_pPmvMessageList; - - g_pPmvMessageList = nullptr; - - if (g_pinnedMessageMap[g_channel].empty()) { - Message msg; - msg.m_type = MessageType::LOADING_PINNED_MESSAGES; - msg.m_author = TmGetString(IDS_PLEASE_WAIT); - msg.m_snowflake = 1; - PmvAddMessage(g_channel, msg); - - GetDiscordInstance()->RequestPinnedMessages(g_channel); - } - - g_pPmvMessageList = MessageList::Create(hWnd, &rect); - g_pPmvMessageList->SetManagedByOwner(true); - g_pPmvMessageList->SetTopDown(true); - g_pPmvMessageList->SetGuild(g_guild); - g_pPmvMessageList->SetChannel(g_channel); - - for (auto& msg : g_pinnedMessageMap[g_channel]) - g_pPmvMessageList->AddMessage(msg); - - g_bActive = true; -} - -void PmvOnLoadedPins(Snowflake channelID, const std::string& data) -{ - nlohmann::json j = nlohmann::json::parse(data); - - if (!j.is_array()) { - assert(!"uh oh"); - return; - } - - g_pinnedMessageMap[g_channel].clear(); - if (g_channel == channelID) - g_pPmvMessageList->ClearMessages(); - - if (j.empty()) { - Message msg; - msg.m_author = " "; - msg.m_type = MessageType::NO_PINNED_MESSAGES; - msg.m_anchor = 1; - msg.m_snowflake = 1; - PmvAddMessage(channelID, msg); - } - else - { - for (auto& msgo : j) - { - Message msg; - msg.Load(msgo, g_guild); - msg.m_anchor = 1; - PmvAddMessage(channelID, msg); - } - } - - // HACK - g_pPmvMessageList->Repaint(); -} - -void PmvOnClickMessage(Snowflake sf) -{ - GetDiscordInstance()->JumpToMessage(g_guild, g_channel, sf); -} - -BOOL CALLBACK PmvDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) - { - case WM_INITDIALOG: - PmvInitialize(hWnd); - return TRUE; - - case WM_COMMAND: - if (wParam == IDCANCEL) { - EndDialog(hWnd, 0); - return TRUE; - } - break; - - case WM_CLICKEDMESSAGE: - EndDialog(hWnd, 0); - PmvOnClickMessage(*(Snowflake*) lParam); - return TRUE; - - case WM_DESTROY: - if (g_pPmvMessageList) - delete g_pPmvMessageList; - g_pPmvMessageList = nullptr; - g_bActive = false; - break; - } - - return FALSE; -} - -void PmvCreate(Snowflake channelID, Snowflake guildID, int x, int y, bool rightJustify) -{ - g_channel = channelID; - g_guild = guildID; - g_appearXY = { x, y }; - g_rightJustify = rightJustify; - - DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_DIALOG_PINNEDMESSAGES), g_Hwnd, PmvDlgProc); -} diff --git a/src/windows/PinnedMessageViewer.hpp b/src/windows/PinnedMessageViewer.hpp deleted file mode 100644 index b557964..0000000 --- a/src/windows/PinnedMessageViewer.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once -#define WIN32_LEAN_AND_MEAN -#include -#include -#include "../discord/Snowflake.hpp" - -// GET Request: discordapi/channels/$CHANNEL_ID/pins -// RESPONSE: Array of message objects - -void PmvInitialize(HWND hWnd); - -void PmvOnLoadedPins(Snowflake channelID, const std::string& data); - -void PmvCreate(Snowflake channelID, Snowflake guildID, int x, int y, bool rightJustify = false); - -bool PmvIsActive(); diff --git a/vs/DiscordMessenger.vcxproj b/vs/DiscordMessenger.vcxproj index 4a2b18f..2deafc2 100644 --- a/vs/DiscordMessenger.vcxproj +++ b/vs/DiscordMessenger.vcxproj @@ -368,7 +368,7 @@ - + @@ -420,7 +420,7 @@ - +