summaryrefslogtreecommitdiff
path: root/protocols/JabberG
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2020-06-29 19:00:02 +0300
committerGeorge Hazan <ghazan@miranda.im>2020-06-29 19:00:02 +0300
commit456293e5f1d7373d1c7a3a0b8888a9dc28b6945d (patch)
treed0a5ce3a45cb64497d98f52b73ebf6356ac05c29 /protocols/JabberG
parent61884f90293ee814791f0594d4388a8244b3511e (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.cpp59
-rw-r--r--protocols/JabberG/src/jabber_menu.cpp10
-rwxr-xr-xprotocols/JabberG/src/jabber_proto.cpp1
-rwxr-xr-xprotocols/JabberG/src/jabber_proto.h12
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);