From 1a5dc583b048727752b8f72df676ec408908041f Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sun, 28 Nov 2021 17:34:41 +0300 Subject: user typing notification for Discord group chats --- src/core/stdmsg/src/msgdialog.cpp | 37 +++++++++++++++++++++---------------- src/core/stdmsg/src/msgs.h | 4 +--- src/mir_app/src/chat.h | 1 + src/mir_app/src/chat_manager.cpp | 14 ++++++++++++++ src/mir_app/src/chat_svc.cpp | 3 +++ src/mir_app/src/chat_tools.cpp | 1 + src/mir_app/src/mir_app.def | 1 + src/mir_app/src/mir_app64.def | 1 + src/mir_app/src/srmm_base.cpp | 5 +++++ 9 files changed, 48 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/core/stdmsg/src/msgdialog.cpp b/src/core/stdmsg/src/msgdialog.cpp index a115908a84..12746815e4 100644 --- a/src/core/stdmsg/src/msgdialog.cpp +++ b/src/core/stdmsg/src/msgdialog.cpp @@ -442,11 +442,11 @@ void CMsgDialog::OnType(CTimer*) } else { if (m_nTypeSecs) { - wchar_t szBuf[256]; - wchar_t *szContactName = Clist_GetContactDisplayName(m_hContact); HICON hTyping = Skin_LoadIcon(SKINICON_OTHER_TYPING); - mir_snwprintf(szBuf, TranslateT("%s is typing a message..."), szContactName); + wchar_t szBuf[256]; + mir_snwprintf(szBuf, TranslateT("%s is typing a message..."), + (m_pUserTyping) ? m_pUserTyping->pszNick : Clist_GetContactDisplayName(m_hContact)); m_nTypeSecs--; SendMessage(m_pOwner->m_hwndStatus, SB_SETTEXT, 0, (LPARAM)szBuf); @@ -1427,28 +1427,33 @@ void CMsgDialog::NotifyTyping(int mode) if (!m_szProto) return; - int protoStatus = Proto_GetStatus(m_szProto); - DWORD protoCaps = CallProtoService(m_szProto, PS_GETCAPS, PFLAGNUM_1, 0); DWORD typeCaps = CallProtoService(m_szProto, PS_GETCAPS, PFLAGNUM_4, 0); - if (!(typeCaps & PF4_SUPPORTTYPING)) return; + int protoStatus = Proto_GetStatus(m_szProto); if (protoStatus < ID_STATUS_ONLINE) return; - if (protoCaps & PF1_VISLIST && db_get_w(m_hContact, m_szProto, "ApparentMode", 0) == ID_STATUS_OFFLINE) - return; + if (isChat()) { + m_nTypeMode = mode; + Chat_DoEventHook(m_si, GC_USER_TYPNOTIFY, 0, 0, m_nTypeMode); + } + else { + DWORD protoCaps = CallProtoService(m_szProto, PS_GETCAPS, PFLAGNUM_1, 0); + if (protoCaps & PF1_VISLIST && db_get_w(m_hContact, m_szProto, "ApparentMode", 0) == ID_STATUS_OFFLINE) + return; - if (protoCaps & PF1_INVISLIST && protoStatus == ID_STATUS_INVISIBLE && db_get_w(m_hContact, m_szProto, "ApparentMode", 0) != ID_STATUS_ONLINE) - return; + if (protoCaps & PF1_INVISLIST && protoStatus == ID_STATUS_INVISIBLE && db_get_w(m_hContact, m_szProto, "ApparentMode", 0) != ID_STATUS_ONLINE) + return; - if (!g_dat.bTypingUnknown && !Contact_OnList(m_hContact)) - return; + if (!g_dat.bTypingUnknown && !Contact_OnList(m_hContact)) + return; - // End user check - m_nTypeMode = mode; - CallService(MS_PROTO_SELFISTYPING, m_hContact, m_nTypeMode); + // End user check + m_nTypeMode = mode; + CallService(MS_PROTO_SELFISTYPING, m_hContact, m_nTypeMode); + } } void CMsgDialog::RemakeLog() @@ -1679,5 +1684,5 @@ void CMsgDialog::UpdateTitle() void CMsgDialog::UserTyping(int nSecs) { - m_nTypeSecs = (nSecs > 0) ? nSecs : 0; + setTyping((nSecs > 0) ? nSecs : 0); } diff --git a/src/core/stdmsg/src/msgs.h b/src/core/stdmsg/src/msgs.h index a2c4f226cc..b5ddbf823d 100644 --- a/src/core/stdmsg/src/msgs.h +++ b/src/core/stdmsg/src/msgs.h @@ -94,14 +94,12 @@ class CMsgDialog : public CSrmmBaseDialog HFONT m_hFont = nullptr; - int m_nTypeSecs = 0, m_nTypeMode = 0; int m_limitAvatarH = 0; - DWORD m_nLastTyping = 0; DWORD m_lastMessage = 0; HANDLE m_hTimeZone = 0; WORD m_wStatus = ID_STATUS_OFFLINE, m_wOldStatus = ID_STATUS_OFFLINE; WORD m_wMinute = 0; - bool m_bIsMeta = false, m_bShowTyping = false, m_bWindowCascaded = false, m_bNoActivate = false; + bool m_bIsMeta = false, m_bWindowCascaded = false, m_bNoActivate = false; public: CMsgDialog(CTabbedWindow *pOwner, MCONTACT hContact); diff --git a/src/mir_app/src/chat.h b/src/mir_app/src/chat.h index 3d158e5beb..37aac65bb0 100644 --- a/src/mir_app/src/chat.h +++ b/src/mir_app/src/chat.h @@ -73,6 +73,7 @@ BOOL SM_SetContactStatus(const wchar_t *pszID, const char *pszModule, c BOOL SM_SetOffline(const char *pszModule, SESSION_INFO *si); BOOL SM_SetStatus(const char *pszModule, SESSION_INFO *si, int wStatus); BOOL SM_TakeStatus(const wchar_t *pszID, const char *pszModule, const wchar_t *pszUID, const wchar_t *pszStatus); +BOOL SM_UserTyping(GCEVENT* gce); SESSION_INFO* SM_FindSession(const wchar_t *pszID, const char *pszModule); SESSION_INFO* SM_FindSessionByIndex(const char *pszModule, int iItem); diff --git a/src/mir_app/src/chat_manager.cpp b/src/mir_app/src/chat_manager.cpp index f2bb050eb9..a815e2732b 100644 --- a/src/mir_app/src/chat_manager.cpp +++ b/src/mir_app/src/chat_manager.cpp @@ -424,6 +424,20 @@ BOOL SM_SetStatus(const char *pszModule, SESSION_INFO *si, int wStatus) return TRUE; } +BOOL SM_UserTyping(GCEVENT *gce) +{ + SESSION_INFO *si = SM_FindSession(gce->pszID.w, gce->pszModule); + if (si == nullptr || si->pDlg == nullptr) + return FALSE; + + USERINFO* ui = UM_FindUser(si, gce->pszUID.w); + if (ui == nullptr) + return FALSE; + + si->pDlg->setTyping(10, ui); + return TRUE; +} + BOOL SM_ChangeNick(const wchar_t *pszID, const char *pszModule, GCEVENT *gce) { if (!pszModule) diff --git a/src/mir_app/src/chat_svc.cpp b/src/mir_app/src/chat_svc.cpp index c831ea9c7e..b28b31d15a 100644 --- a/src/mir_app/src/chat_svc.cpp +++ b/src/mir_app/src/chat_svc.cpp @@ -493,6 +493,9 @@ static INT_PTR CALLBACK sttEventStub(void *_param) bIsHighlighted = g_chatApi.IsHighlighted(nullptr, &gce); break; + case GC_EVENT_TYPING: + return SM_UserTyping(&gce); + case GC_EVENT_JOIN: AddUser(&gce); bIsHighlighted = g_chatApi.IsHighlighted(nullptr, &gce); diff --git a/src/mir_app/src/chat_tools.cpp b/src/mir_app/src/chat_tools.cpp index f334a128b5..fbad9e5bc6 100644 --- a/src/mir_app/src/chat_tools.cpp +++ b/src/mir_app/src/chat_tools.cpp @@ -637,6 +637,7 @@ BOOL IsEventSupported(int eventType) case GC_EVENT_NOTICE: case GC_EVENT_MESSAGE: case GC_EVENT_TOPIC: + case GC_EVENT_TYPING: case GC_EVENT_INFORMATION: case GC_EVENT_ACTION: case GC_EVENT_ADDSTATUS: diff --git a/src/mir_app/src/mir_app.def b/src/mir_app/src/mir_app.def index cdb53fd277..46b27c22b8 100644 --- a/src/mir_app/src/mir_app.def +++ b/src/mir_app/src/mir_app.def @@ -787,3 +787,4 @@ _Netlib_SslPending@4 @874 NONAME _Netlib_SslRead@16 @875 NONAME _Netlib_SslShutdown@4 @876 NONAME _Netlib_SslWrite@12 @877 NONAME +?AllowTyping@CSrmmBaseDialog@@IBE_NXZ @878 NONAME diff --git a/src/mir_app/src/mir_app64.def b/src/mir_app/src/mir_app64.def index ec9a92f9bb..e78b512abf 100644 --- a/src/mir_app/src/mir_app64.def +++ b/src/mir_app/src/mir_app64.def @@ -787,3 +787,4 @@ Netlib_SslPending @874 NONAME Netlib_SslRead @875 NONAME Netlib_SslShutdown @876 NONAME Netlib_SslWrite @877 NONAME +?AllowTyping@CSrmmBaseDialog@@IEBA_NXZ @878 NONAME diff --git a/src/mir_app/src/srmm_base.cpp b/src/mir_app/src/srmm_base.cpp index 4557c7bbb9..02f0b0b29b 100644 --- a/src/mir_app/src/srmm_base.cpp +++ b/src/mir_app/src/srmm_base.cpp @@ -555,6 +555,11 @@ void CSrmmBaseDialog::AddLog() m_pLog->Clear(); } +bool CSrmmBaseDialog::AllowTyping() const +{ + return isChat() ? m_si->iType != GCW_SERVER : true; +} + void CSrmmBaseDialog::ClearLog() { m_pLog->Clear(); -- cgit v1.2.3