diff options
-rw-r--r-- | include/m_chat.h | 3 | ||||
-rw-r--r-- | protocols/Telegram/src/groupchat.cpp | 44 | ||||
-rw-r--r-- | protocols/Telegram/src/server.cpp | 5 | ||||
-rw-r--r-- | src/mir_app/src/chat.h | 2 | ||||
-rw-r--r-- | src/mir_app/src/chat_manager.cpp | 292 | ||||
-rw-r--r-- | src/mir_app/src/chat_svc.cpp | 5 | ||||
-rw-r--r-- | src/mir_app/src/chat_tools.cpp | 1 |
7 files changed, 200 insertions, 152 deletions
diff --git a/include/m_chat.h b/include/m_chat.h index 4a05f7ea80..e747388245 100644 --- a/include/m_chat.h +++ b/include/m_chat.h @@ -338,6 +338,9 @@ MIR_APP_DLL(struct SESSION_INFO*) Chat_NewSession( // dwItemData - ON/OFF
#define GC_EVENT_TYPING 0x1001
+// same as GC_EVENT_ADDSTATUS but wipes all another statuses before
+#define GC_EVENT_SETSTATUS 0x1002
+
// GC_EVENT_SETCONTACTSTATUS - sets status icon for contact
// pszUID - Unique identifier of the one who receives a new status
// dwItemData - (DWORD)ID_STATUS_* or zero to remove status icon
diff --git a/protocols/Telegram/src/groupchat.cpp b/protocols/Telegram/src/groupchat.cpp index e0eec733c5..618f415922 100644 --- a/protocols/Telegram/src/groupchat.cpp +++ b/protocols/Telegram/src/groupchat.cpp @@ -17,6 +17,21 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include "stdafx.h" +static const wchar_t* getRoleById(uint32_t ID) +{ + switch (ID) { + case TD::chatMemberStatusCreator::ID: + return TranslateT("Creator"); + + case TD::chatMemberStatusAdministrator::ID: + return TranslateT("Admin"); + + case TD::chatMemberStatusMember::ID: + default: + return TranslateT("Participant"); + } +} + void CTelegramProto::InitGroupChat(TG_USER *pUser, const TD::chat *pChat) { if (pUser->m_si) @@ -102,21 +117,6 @@ void CTelegramProto::GcAddMembers(TG_USER *pChat, const TD::array<TD::object_ptr { for (auto &it : pMembers) { auto *pMember = it.get(); - const wchar_t *pwszRole; - - switch (pMember->status_->get_id()) { - case TD::chatMemberStatusCreator::ID: - pwszRole = TranslateT("Creator"); - break; - case TD::chatMemberStatusAdministrator::ID: - pwszRole = TranslateT("Admin"); - break; - case TD::chatMemberStatusMember::ID: - default: - pwszRole = TranslateT("Participant"); - break; - } - if (pMember->member_id_->get_id() != TD::messageSenderUser::ID) continue; @@ -130,7 +130,7 @@ void CTelegramProto::GcAddMembers(TG_USER *pChat, const TD::array<TD::object_ptr GCEVENT gce = { pChat->m_si, GC_EVENT_JOIN }; gce.pszUID.w = wszUserId; - gce.pszStatus.w = pwszRole; + gce.pszStatus.w = getRoleById(pMember->status_->get_id()); if (bSilent) gce.dwFlags = GCEF_SILENT; @@ -416,5 +416,15 @@ void CTelegramProto::ProcessSuperGroup(TD::updateSupergroup *pObj) pUser->wszNick = getName(pGroup->group->usernames_.get()); pUser->wszLastName.Format(TranslateT("%d member(s)"), pGroup->group->member_count_); } - else AddUser(tmp.id, true); + else { + auto *pChat = AddUser(tmp.id, true); + if (auto *si = pChat->m_si) { + CMStringW wszUserId(FORMAT, L"%lld", m_iOwnId); + + GCEVENT gce = { si, GC_EVENT_SETSTATUS }; + gce.pszUID.w = wszUserId; + gce.pszStatus.w = getRoleById(iStatusId); + Chat_Event(&gce); + } + } } diff --git a/protocols/Telegram/src/server.cpp b/protocols/Telegram/src/server.cpp index acf31c7e96..d9dde02216 100644 --- a/protocols/Telegram/src/server.cpp +++ b/protocols/Telegram/src/server.cpp @@ -916,9 +916,10 @@ void CTelegramProto::ProcessUser(TD::updateUser *pObj) auto storedId = getMStringA(pu->hContact, DBKEY_AVATAR_HASH);
if (remoteId != storedId.c_str()) {
if (!remoteId.empty()) {
- if (pu)
+ if (pu) {
pu->szAvatarHash = remoteId.c_str();
- setString(pu->hContact, DBKEY_AVATAR_HASH, remoteId.c_str());
+ setString(pu->hContact, DBKEY_AVATAR_HASH, remoteId.c_str());
+ }
SendQuery(new TD::downloadFile(pSmall->id_, 5, 0, 0, false));
}
else delSetting(pu->hContact, DBKEY_AVATAR_HASH);
diff --git a/src/mir_app/src/chat.h b/src/mir_app/src/chat.h index 6248c15e8e..430c694e8c 100644 --- a/src/mir_app/src/chat.h +++ b/src/mir_app/src/chat.h @@ -72,8 +72,8 @@ MODULEINFO* MM_FindModule(const char *pszModule); LOGINFO* SM_AddEvent(SESSION_INFO *si, GCEVENT *gce, bool bIsHighlighted);
BOOL SM_ChangeNick(SESSION_INFO *si, GCEVENT *gce);
void SM_FreeSession(SESSION_INFO *si);
-char* SM_GetUsers(SESSION_INFO *si);
BOOL SM_GiveStatus(SESSION_INFO *si, const wchar_t *pszUID, const wchar_t *pszStatus);
+BOOL SM_AssignStatus(SESSION_INFO *si, const wchar_t *pszUID, const wchar_t *pszStatus);
void SM_RemoveAll(void);
BOOL SM_RemoveUser(SESSION_INFO *si, const wchar_t *pszUID);
BOOL SM_SetContactStatus(SESSION_INFO *si, const wchar_t *pszUID, uint16_t wStatus);
diff --git a/src/mir_app/src/chat_manager.cpp b/src/mir_app/src/chat_manager.cpp index 284d51c559..613bbd3f48 100644 --- a/src/mir_app/src/chat_manager.cpp +++ b/src/mir_app/src/chat_manager.cpp @@ -153,6 +153,153 @@ MIR_APP_DLL(SESSION_INFO*) Chat_Find(const wchar_t *pszID, const char *pszModule return g_arSessions.find(tmp);
}
+/////////////////////////////////////////////////////////////////////////////////////////
+// Chat user manager
+
+USERINFO* UM_AddUser(SESSION_INFO *si, const wchar_t *pszUID, const wchar_t *pszNick, uint16_t wStatus)
+{
+ if (!si || !pszUID || !pszNick)
+ return nullptr;
+
+ mir_cslock lck(si->csLock);
+ auto *pUser = UM_FindUser(si, pszUID);
+ if (pUser == nullptr) {
+ pUser = new USERINFO();
+ replaceStrW(pUser->pszUID, pszUID);
+ si->getUserList().insert(pUser);
+ }
+
+ replaceStrW(pUser->pszNick, pszNick);
+ pUser->Status = wStatus;
+ return pUser;
+}
+
+static int UM_CompareItem(const USERINFO *u1, const USERINFO *u2)
+{
+ uint16_t dw1 = u1->Status;
+ uint16_t dw2 = u2->Status;
+
+ for (int i = 0; i < 8; i++) {
+ if ((dw1 & 1) && !(dw2 & 1))
+ return -1;
+ if ((dw2 & 1) && !(dw1 & 1))
+ return 1;
+ if ((dw1 & 1) && (dw2 & 1))
+ break;
+
+ dw1 = dw1 >> 1;
+ dw2 = dw2 >> 1;
+ }
+ return mir_wstrcmpi(u1->pszNick, u2->pszNick);
+}
+
+static USERINFO* UM_GiveStatus(SESSION_INFO *si, const wchar_t *pszUID, uint16_t status)
+{
+ USERINFO *ui = UM_FindUser(si, pszUID);
+ if (ui == nullptr)
+ return nullptr;
+
+ ui->Status |= status;
+ return ui;
+}
+
+static USERINFO* UM_SetStatus(SESSION_INFO *si, const wchar_t *pszUID, uint16_t status)
+{
+ USERINFO *ui = UM_FindUser(si, pszUID);
+ if (ui == nullptr)
+ return nullptr;
+
+ if (ui->Status == status)
+ return nullptr;
+
+ ui->Status = status;
+ return ui;
+}
+
+static USERINFO* UM_SetContactStatus(SESSION_INFO *si, const wchar_t *pszUID, uint16_t status)
+{
+ USERINFO *ui = UM_FindUser(si, pszUID);
+ if (ui == nullptr)
+ return nullptr;
+
+ ui->ContactStatus = status;
+ return ui;
+}
+
+BOOL UM_SetStatusEx(SESSION_INFO *si, const wchar_t *pszText, int flags)
+{
+ int bOnlyMe = (flags & GC_SSE_ONLYLISTED) != 0, bSetStatus = (flags & GC_SSE_ONLINE) != 0;
+ char cDelimiter = (flags & GC_SSE_TABDELIMITED) ? '\t' : ' ';
+
+ if (bOnlyMe) {
+ USERINFO *ui = UM_FindUser(si, pszText);
+ if (ui == nullptr)
+ return FALSE;
+
+ ui->iStatusEx = (bSetStatus) ? 1 : 0;
+ return TRUE;
+ }
+
+ for (auto &ui : si->getUserList()) {
+ ui->iStatusEx = 0;
+
+ if (pszText != nullptr) {
+ wchar_t *s = (wchar_t *)wcsstr(pszText, ui->pszUID);
+ if (s) {
+ ui->iStatusEx = 0;
+ if (s == pszText || s[-1] == cDelimiter) {
+ size_t len = mir_wstrlen(ui->pszUID);
+ if (s[len] == cDelimiter || s[len] == '\0')
+ ui->iStatusEx = bSetStatus ? 1 : 0;
+ }
+ }
+ }
+ }
+ return TRUE;
+}
+
+static USERINFO *UM_TakeStatus(SESSION_INFO *si, const wchar_t *pszUID, uint16_t status)
+{
+ USERINFO *ui = UM_FindUser(si, pszUID);
+ if (ui == nullptr)
+ return nullptr;
+
+ ui->Status &= ~status;
+ return ui;
+}
+
+static wchar_t *UM_FindUserAutoComplete(SESSION_INFO *si, const wchar_t *pszOriginal, const wchar_t *pszCurrent)
+{
+ if (!si || !pszOriginal || !pszCurrent)
+ return nullptr;
+
+ wchar_t *pszName = nullptr;
+ for (auto &ui : si->getUserList())
+ if (ui->pszNick && mir_wstrstri(ui->pszNick, pszOriginal) == ui->pszNick)
+ if (mir_wstrcmpi(ui->pszNick, pszCurrent) > 0 && (!pszName || mir_wstrcmpi(ui->pszNick, pszName) < 0))
+ pszName = ui->pszNick;
+
+ return pszName;
+}
+
+BOOL UM_RemoveAll(SESSION_INFO *si)
+{
+ if (!si)
+ return FALSE;
+
+ if (!si->pParent) {
+ for (auto &ui : si->arUsers) {
+ mir_free(ui->pszUID);
+ mir_free(ui->pszNick);
+ }
+ si->arUsers.destroy();
+ }
+ return TRUE;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Chat session manager
+
BOOL SM_SetOffline(const char *pszModule, SESSION_INFO *si)
{
if (si == nullptr) {
@@ -254,7 +401,18 @@ BOOL SM_GiveStatus(SESSION_INFO *si, const wchar_t *pszUID, const wchar_t *pszSt if (si == nullptr)
return FALSE;
- USERINFO *ui = g_chatApi.UM_GiveStatus(si, pszUID, TM_StringToWord(si->pStatuses, pszStatus));
+ USERINFO *ui = UM_GiveStatus(si, pszUID, TM_StringToWord(si->pStatuses, pszStatus));
+ if (ui && si->pDlg)
+ si->pDlg->UpdateNickList();
+ return TRUE;
+}
+
+BOOL SM_AssignStatus(SESSION_INFO *si, const wchar_t *pszUID, const wchar_t *pszStatus)
+{
+ if (si == nullptr)
+ return FALSE;
+
+ USERINFO *ui = UM_SetStatus(si, pszUID, TM_StringToWord(si->pStatuses, pszStatus));
if (ui && si->pDlg)
si->pDlg->UpdateNickList();
return TRUE;
@@ -265,7 +423,7 @@ BOOL SM_SetContactStatus(SESSION_INFO *si, const wchar_t *pszUID, uint16_t wStat if (si == nullptr)
return FALSE;
- USERINFO *ui = g_chatApi.UM_SetContactStatus(si, pszUID, wStatus);
+ USERINFO *ui = UM_SetContactStatus(si, pszUID, wStatus);
if (ui && si->pDlg)
si->pDlg->UpdateNickList();
return TRUE;
@@ -570,136 +728,6 @@ void UM_SortKeys(SESSION_INFO *si) /////////////////////////////////////////////////////////////////////////////////////////
-USERINFO* UM_AddUser(SESSION_INFO *si, const wchar_t *pszUID, const wchar_t *pszNick, uint16_t wStatus)
-{
- if (!si || !pszUID || !pszNick)
- return nullptr;
-
- mir_cslock lck(si->csLock);
- auto *pUser = UM_FindUser(si, pszUID);
- if (pUser == nullptr) {
- pUser = new USERINFO();
- replaceStrW(pUser->pszUID, pszUID);
- si->getUserList().insert(pUser);
- }
-
- replaceStrW(pUser->pszNick, pszNick);
- pUser->Status = wStatus;
- return pUser;
-}
-
-static int UM_CompareItem(const USERINFO *u1, const USERINFO *u2)
-{
- uint16_t dw1 = u1->Status;
- uint16_t dw2 = u2->Status;
-
- for (int i = 0; i < 8; i++) {
- if ((dw1 & 1) && !(dw2 & 1))
- return -1;
- if ((dw2 & 1) && !(dw1 & 1))
- return 1;
- if ((dw1 & 1) && (dw2 & 1))
- break;
-
- dw1 = dw1 >> 1;
- dw2 = dw2 >> 1;
- }
- return mir_wstrcmpi(u1->pszNick, u2->pszNick);
-}
-
-static USERINFO* UM_GiveStatus(SESSION_INFO *si, const wchar_t *pszUID, uint16_t status)
-{
- USERINFO *ui = UM_FindUser(si, pszUID);
- if (ui == nullptr)
- return nullptr;
-
- ui->Status |= status;
- return ui;
-}
-
-static USERINFO* UM_SetContactStatus(SESSION_INFO *si, const wchar_t *pszUID, uint16_t status)
-{
- USERINFO *ui = UM_FindUser(si, pszUID);
- if (ui == nullptr)
- return nullptr;
-
- ui->ContactStatus = status;
- return ui;
-}
-
-BOOL UM_SetStatusEx(SESSION_INFO *si, const wchar_t* pszText, int flags)
-{
- int bOnlyMe = (flags & GC_SSE_ONLYLISTED) != 0, bSetStatus = (flags & GC_SSE_ONLINE) != 0;
- char cDelimiter = (flags & GC_SSE_TABDELIMITED) ? '\t' : ' ';
-
- if (bOnlyMe) {
- USERINFO *ui = UM_FindUser(si, pszText);
- if (ui == nullptr)
- return FALSE;
-
- ui->iStatusEx = (bSetStatus) ? 1 : 0;
- return TRUE;
- }
-
- for (auto &ui : si->getUserList()) {
- ui->iStatusEx = 0;
-
- if (pszText != nullptr) {
- wchar_t *s = (wchar_t *)wcsstr(pszText, ui->pszUID);
- if (s) {
- ui->iStatusEx = 0;
- if (s == pszText || s[-1] == cDelimiter) {
- size_t len = mir_wstrlen(ui->pszUID);
- if (s[len] == cDelimiter || s[len] == '\0')
- ui->iStatusEx = bSetStatus ? 1 : 0;
- }
- }
- }
- }
- return TRUE;
-}
-
-static USERINFO* UM_TakeStatus(SESSION_INFO *si, const wchar_t *pszUID, uint16_t status)
-{
- USERINFO *ui = UM_FindUser(si, pszUID);
- if (ui == nullptr)
- return nullptr;
-
- ui->Status &= ~status;
- return ui;
-}
-
-static wchar_t* UM_FindUserAutoComplete(SESSION_INFO *si, const wchar_t* pszOriginal, const wchar_t* pszCurrent)
-{
- if (!si || !pszOriginal || !pszCurrent)
- return nullptr;
-
- wchar_t *pszName = nullptr;
- for (auto &ui : si->getUserList())
- if (ui->pszNick && mir_wstrstri(ui->pszNick, pszOriginal) == ui->pszNick)
- if (mir_wstrcmpi(ui->pszNick, pszCurrent) > 0 && (!pszName || mir_wstrcmpi(ui->pszNick, pszName) < 0))
- pszName = ui->pszNick;
-
- return pszName;
-}
-
-BOOL UM_RemoveAll(SESSION_INFO *si)
-{
- if (!si)
- return FALSE;
-
- if (!si->pParent) {
- for (auto &ui : si->arUsers) {
- mir_free(ui->pszUID);
- mir_free(ui->pszNick);
- }
- si->arUsers.destroy();
- }
- return TRUE;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
static void CreateNick(const SESSION_INFO *, const LOGINFO *lin, CMStringW &wszNick)
{
if (lin->ptszNick) {
diff --git a/src/mir_app/src/chat_svc.cpp b/src/mir_app/src/chat_svc.cpp index 006459273c..28bfcba762 100644 --- a/src/mir_app/src/chat_svc.cpp +++ b/src/mir_app/src/chat_svc.cpp @@ -494,6 +494,11 @@ static BOOL HandleChatEvent(GCEVENT &gce, int bManyFix) bIsHighlighted = g_chatApi.IsHighlighted(si, &gce);
break;
+ case GC_EVENT_SETSTATUS:
+ SM_AssignStatus(si, gce.pszUID.w, gce.pszStatus.w);
+ bIsHighlighted = g_chatApi.IsHighlighted(si, &gce);
+ break;
+
case GC_EVENT_REMOVESTATUS:
SM_TakeStatus(si, gce.pszUID.w, gce.pszStatus.w);
bIsHighlighted = g_chatApi.IsHighlighted(si, &gce);
diff --git a/src/mir_app/src/chat_tools.cpp b/src/mir_app/src/chat_tools.cpp index 4d532fa871..2692678a69 100644 --- a/src/mir_app/src/chat_tools.cpp +++ b/src/mir_app/src/chat_tools.cpp @@ -633,6 +633,7 @@ BOOL IsEventSupported(int eventType) case GC_EVENT_INFORMATION:
case GC_EVENT_ACTION:
case GC_EVENT_ADDSTATUS:
+ case GC_EVENT_SETSTATUS:
case GC_EVENT_REMOVESTATUS:
case GC_EVENT_SETCONTACTSTATUS:
return TRUE;
|