diff options
author | George Hazan <ghazan@miranda.im> | 2020-06-29 19:00:02 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2020-06-29 19:00:02 +0300 |
commit | 456293e5f1d7373d1c7a3a0b8888a9dc28b6945d (patch) | |
tree | d0a5ce3a45cb64497d98f52b73ebf6356ac05c29 /protocols/JabberG | |
parent | 61884f90293ee814791f0594d4388a8244b3511e (diff) |
fixes #2453 (Jabber: add ability to load whole history via Message Archive Management)
Diffstat (limited to 'protocols/JabberG')
-rw-r--r-- | protocols/JabberG/src/jabber_mam.cpp | 59 | ||||
-rw-r--r-- | protocols/JabberG/src/jabber_menu.cpp | 10 | ||||
-rwxr-xr-x | protocols/JabberG/src/jabber_proto.cpp | 1 | ||||
-rwxr-xr-x | protocols/JabberG/src/jabber_proto.h | 12 |
4 files changed, 74 insertions, 8 deletions
diff --git a/protocols/JabberG/src/jabber_mam.cpp b/protocols/JabberG/src/jabber_mam.cpp index 43e80d76b8..f369dcb0c4 100644 --- a/protocols/JabberG/src/jabber_mam.cpp +++ b/protocols/JabberG/src/jabber_mam.cpp @@ -78,3 +78,62 @@ void CJabberProto::MamRetrieveMissingMessages() set << XCHILD("after", szLastId); m_ThreadInfo->send(iq); } + +///////////////////////////////////////////////////////////////////////////////////////// +// Contact's history loader + +void CJabberProto::OnIqResultRsm(const TiXmlElement *iqNode, CJabberIqInfo *pInfo) +{ + if (auto *fin = XmlGetChildByTag(iqNode, "fin", "xmlns", JABBER_FEAT_MAM)) { + // if dataset is complete, there's nothing more to do + if (!mir_strcmp(XmlGetAttr(fin, "complete"), "true")) + return; + + auto *lastId = XmlGetChildText(fin, "last"); + if (lastId) { + ptrA jid(getUStringA(pInfo->GetHContact(), "jid")); + + auto *pReq = AddIQ(&CJabberProto::OnIqResultRsm, JABBER_IQ_TYPE_SET); + pReq->SetParamsToParse(JABBER_IQ_PARSE_FROM); + + XmlNodeIq iq(pReq); + auto *query = iq << XCHILDNS("query", JABBER_FEAT_MAM); + auto *x = query << XCHILDNS("x", "jabber:x:data") << XATTR("type", "submit"); + x << XCHILD("var", "FORM_TYPE") << XATTR("type", "hidden") << XCHILD("value", JABBER_FEAT_MAM); + x << XCHILD("var", "with") << XCHILD("value", jid); + auto *rsm = query << XCHILDNS("set", "http://jabber.org/protocol/rsm"); + rsm << XCHILD("max", "100"); + rsm << XCHILD("after", lastId); + m_ThreadInfo->send(iq); + } + } +} + +INT_PTR __cdecl CJabberProto::OnMenuLoadHistory(WPARAM hContact, LPARAM) +{ + if (hContact == 0) + return 0; + + // wipe out old history first + DB::ECPTR pCursor(DB::Events(hContact)); + while (pCursor.FetchNext()) + pCursor.DeleteEvent(); + + // load remaining items from server + if (m_bJabberOnline) { + ptrA jid(getUStringA(hContact, "jid")); + if (jid != nullptr) { + auto *pReq = AddIQ(&CJabberProto::OnIqResultRsm, JABBER_IQ_TYPE_SET); + pReq->SetParamsToParse(JABBER_IQ_PARSE_FROM); + + XmlNodeIq iq(pReq); + auto *query = iq << XCHILDNS("query", JABBER_FEAT_MAM); + auto *x = query << XCHILDNS("x", "jabber:x:data") << XATTR("type", "submit"); + x << XCHILD("var", "FORM_TYPE") << XATTR("type", "hidden") << XCHILD("value", JABBER_FEAT_MAM); + x << XCHILD("var", "with") << XCHILD("value", jid); + query << XCHILDNS("set", "http://jabber.org/protocol/rsm") << XCHILD("max", "100"); + m_ThreadInfo->send(iq); + } + } + return 0; +} diff --git a/protocols/JabberG/src/jabber_menu.cpp b/protocols/JabberG/src/jabber_menu.cpp index 6bb8ec5444..87db94d7a3 100644 --- a/protocols/JabberG/src/jabber_menu.cpp +++ b/protocols/JabberG/src/jabber_menu.cpp @@ -266,6 +266,7 @@ int CJabberProto::OnPrebuildContactMenu(WPARAM hContact, LPARAM) if (hContact == 0)
return 0;
+ Menu_ShowItem(GetMenuItem(PROTO_MENU_LOAD_HISTORY), false);
bool bIsChatRoom = isChatRoom(hContact);
bool bIsTransport = getBool(hContact, "IsTransport", false);
@@ -276,6 +277,9 @@ int CJabberProto::OnPrebuildContactMenu(WPARAM hContact, LPARAM) for (int i = 0; i < _countof(PresenceModeArray); i++)
Menu_ModifyItem(g_hMenuDirectPresence[i + 1], nullptr, Skin_GetProtoIcon(m_szModuleName, PresenceModeArray[i].mode));
+ if (m_ThreadInfo && (m_ThreadInfo->jabberServerCaps & JABBER_CAPS_MAM))
+ Menu_ShowItem(GetMenuItem(PROTO_MENU_LOAD_HISTORY), true);
+
if (bIsChatRoom) {
ptrA roomid(getUStringA(hContact, "ChatRoomID"));
if (ListGetItemPtr(LIST_BOOKMARK, roomid) == nullptr)
@@ -301,9 +305,9 @@ int CJabberProto::OnPrebuildContactMenu(WPARAM hContact, LPARAM) return 0;
bool bCtrlPressed = (GetKeyState(VK_CONTROL) & 0x8000) != 0;
- Menu_ShowItem(m_hmiReqAuth, item->subscription == SUB_FROM || item->subscription == SUB_NONE || bCtrlPressed);
- Menu_ShowItem(m_hmiGrantAuth, bCtrlPressed);
- Menu_ShowItem(m_hmiRevokeAuth, item->subscription == SUB_FROM || item->subscription == SUB_BOTH || bCtrlPressed);
+ Menu_ShowItem(GetMenuItem(PROTO_MENU_REQ_AUTH), item->subscription == SUB_FROM || item->subscription == SUB_NONE || bCtrlPressed);
+ Menu_ShowItem(GetMenuItem(PROTO_MENU_GRANT_AUTH), bCtrlPressed);
+ Menu_ShowItem(GetMenuItem(PROTO_MENU_REVOKE_AUTH), item->subscription == SUB_FROM || item->subscription == SUB_BOTH || bCtrlPressed);
Menu_ShowItem(g_hMenuCommands, ((jcb & JABBER_CAPS_COMMANDS) != 0) || bCtrlPressed);
Menu_ShowItem(g_hMenuSendNote, TRUE);
diff --git a/protocols/JabberG/src/jabber_proto.cpp b/protocols/JabberG/src/jabber_proto.cpp index a28fcc7b87..685f39eb14 100755 --- a/protocols/JabberG/src/jabber_proto.cpp +++ b/protocols/JabberG/src/jabber_proto.cpp @@ -167,6 +167,7 @@ CJabberProto::CJabberProto(const char *aProtoName, const wchar_t *aUserName) : CreateProtoService(PS_MENU_REQAUTH, &CJabberProto::OnMenuHandleRequestAuth);
CreateProtoService(PS_MENU_GRANTAUTH, &CJabberProto::OnMenuHandleGrantAuth);
CreateProtoService(PS_MENU_REVOKEAUTH, &CJabberProto::OnMenuHandleRevokeAuth);
+ CreateProtoService(PS_MENU_LOADHISTORY, &CJabberProto::OnMenuLoadHistory);
CreateProtoService(JS_DB_GETEVENTTEXT_CHATSTATES, &CJabberProto::OnGetEventTextChatStates);
CreateProtoService(JS_DB_GETEVENTTEXT_PRESENCE, &CJabberProto::OnGetEventTextPresence);
diff --git a/protocols/JabberG/src/jabber_proto.h b/protocols/JabberG/src/jabber_proto.h index 5dd2f0e8fc..9a0588d6e1 100755 --- a/protocols/JabberG/src/jabber_proto.h +++ b/protocols/JabberG/src/jabber_proto.h @@ -640,22 +640,24 @@ struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface //---- jabber_mam.cpp ----------------------------------------------------------------
void OnIqResultMamInfo(const TiXmlElement *iqNode, CJabberIqInfo *pInfo);
+ void OnIqResultRsm(const TiXmlElement *iqNode, CJabberIqInfo *pInfo);
void MamRetrieveMissingMessages(void);
void MamSetMode(int iNewMode);
//---- jabber_menu.cpp ---------------------------------------------------------------
- INT_PTR __cdecl OnMenuHandleRequestAuth(WPARAM wParam, LPARAM lParam);
- INT_PTR __cdecl OnMenuHandleGrantAuth(WPARAM wParam, LPARAM lParam);
- INT_PTR __cdecl OnMenuOptions(WPARAM wParam, LPARAM lParam);
- INT_PTR __cdecl OnMenuTransportLogin(WPARAM wParam, LPARAM lParam);
- INT_PTR __cdecl OnMenuTransportResolve(WPARAM wParam, LPARAM lParam);
INT_PTR __cdecl OnMenuBookmarkAdd(WPARAM wParam, LPARAM lParam);
+ INT_PTR __cdecl OnMenuHandleGrantAuth(WPARAM wParam, LPARAM lParam);
+ INT_PTR __cdecl OnMenuHandleRequestAuth(WPARAM wParam, LPARAM lParam);
INT_PTR __cdecl OnMenuHandleRevokeAuth(WPARAM wParam, LPARAM lParam);
INT_PTR __cdecl OnMenuHandleResource(WPARAM wParam, LPARAM lParam, LPARAM res);
INT_PTR __cdecl OnMenuHandleDirectPresence(WPARAM wParam, LPARAM lParam, LPARAM res);
+ INT_PTR __cdecl OnMenuLoadHistory(WPARAM wParam, LPARAM lParam);
INT_PTR __cdecl OnMenuSetPriority(WPARAM wParam, LPARAM lParam, LPARAM dwDelta);
+ INT_PTR __cdecl OnMenuOptions(WPARAM wParam, LPARAM lParam);
+ INT_PTR __cdecl OnMenuTransportLogin(WPARAM wParam, LPARAM lParam);
+ INT_PTR __cdecl OnMenuTransportResolve(WPARAM wParam, LPARAM lParam);
void GlobalMenuInit(void);
void GlobalMenuUninit(void);
|