diff options
author | George Hazan <george.hazan@gmail.com> | 2023-11-30 15:03:35 +0300 |
---|---|---|
committer | George Hazan <george.hazan@gmail.com> | 2023-11-30 15:03:35 +0300 |
commit | c1849a9d50be0951bc4b2a5c0f14dbde5a8340e0 (patch) | |
tree | 26d8df5ee844e9755e49c6ca066f3cdbdbbd4730 /src/mir_app | |
parent | 0512d3e3f9f93324830892f43095e214e743f50c (diff) |
fixes #3985 (Telegram: изменение статуса отображается лишь после перезапуска)
Diffstat (limited to 'src/mir_app')
-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 |
4 files changed, 167 insertions, 133 deletions
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;
|