| 3905 | } |
| 3906 | |
| 3907 | bool MessageList::SendToMessage(Snowflake sf, bool requestIfNeeded, bool forceInvalidate) |
| 3908 | { |
| 3909 | if (sf == UINT64_MAX) |
| 3910 | sf = GetDiscordInstance()->GetChannel(m_channelID)->m_lastSentMsg; |
| 3911 | |
| 3912 | m_messageSentTo = sf; |
| 3913 | m_firstShownMessage = sf; |
| 3914 | auto mi = FindMessage(sf); |
| 3915 | |
| 3916 | if (mi != m_messages.end()) |
| 3917 | { |
| 3918 | int y = 0; |
| 3919 | for (auto iter = m_messages.begin(); iter != mi && iter != m_messages.end(); ++iter) |
| 3920 | y += iter->m_height; |
| 3921 | |
| 3922 | // centers the message |
| 3923 | RECT rcClient{}; |
| 3924 | GetClientRect(m_hwnd, &rcClient); |
| 3925 | |
| 3926 | SCROLLINFO si{}; |
| 3927 | si.cbSize = sizeof(SCROLLINFO); |
| 3928 | si.fMask = SIF_RANGE; |
| 3929 | ri::GetScrollInfo(m_hwnd, SB_VERT, &si); |
| 3930 | |
| 3931 | int yOffs = (rcClient.bottom - rcClient.top) / 2 - mi->m_height / 2; |
| 3932 | y -= yOffs; |
| 3933 | |
| 3934 | if (y < si.nMin) |
| 3935 | y = si.nMin; |
| 3936 | if (y > si.nMax) |
| 3937 | y = si.nMax; |
| 3938 | |
| 3939 | // Just scroll there |
| 3940 | si.fMask = SIF_POS; |
| 3941 | si.nPos = y; |
| 3942 | ri::SetScrollInfo(m_hwnd, SB_VERT, &si, true); |
| 3943 | |
| 3944 | FlashMessage(mi->m_msg->m_snowflake); |
| 3945 | |
| 3946 | if (forceInvalidate) |
| 3947 | InvalidateRect(m_hwnd, NULL, MayErase()); |
| 3948 | else |
| 3949 | SendMessage(m_hwnd, WM_VSCROLL, SB_ENDSCROLL, 0); |
| 3950 | |
| 3951 | bool isLoadGap = !mi->m_msg->IsLoadGap(); |
| 3952 | |
| 3953 | m_messageSentTo = 0; |
| 3954 | RefetchMessages(sf, true); |
| 3955 | |
| 3956 | return isLoadGap; |
| 3957 | } |
| 3958 | |
| 3959 | if (!requestIfNeeded) |
| 3960 | return false; |
| 3961 | |
| 3962 | // check if that message is loaded though |
| 3963 | if (GetMessageCache()->IsMessageLoaded(m_channelID, sf)) { |
| 3964 | m_messages.clear(); |
no test coverage detected