Line data Source code
1 : /*
2 : * Copyright (C) 2004-2026 Savoir-faire Linux Inc.
3 : *
4 : * This program is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 3 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * This program is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 : */
17 :
18 : #ifdef HAVE_CONFIG_H
19 : #include "config.h"
20 : #endif
21 :
22 : #include "conversation_interface.h"
23 :
24 : #include <cerrno>
25 : #include <cstring>
26 :
27 : #include "logger.h"
28 : #include "manager.h"
29 : #include "jamidht/jamiaccount.h"
30 : #include "jamidht/conversation_module.h"
31 :
32 : namespace libjami {
33 :
34 : std::string
35 117 : startConversation(const std::string& accountId)
36 : {
37 117 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
38 117 : if (auto* convModule = acc->convModule(true))
39 117 : return convModule->startConversation();
40 0 : return {};
41 : }
42 :
43 : void
44 136 : acceptConversationRequest(const std::string& accountId, const std::string& conversationId)
45 : {
46 136 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
47 136 : if (auto* convModule = acc->convModule(true))
48 136 : convModule->acceptConversationRequest(conversationId);
49 136 : }
50 :
51 : void
52 3 : declineConversationRequest(const std::string& accountId, const std::string& conversationId)
53 : {
54 3 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
55 3 : acc->declineConversationRequest(conversationId);
56 3 : }
57 :
58 : bool
59 9 : removeConversation(const std::string& accountId, const std::string& conversationId)
60 : {
61 9 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
62 9 : if (auto* convModule = acc->convModule(true))
63 9 : return convModule->removeConversation(conversationId);
64 0 : return false;
65 : }
66 :
67 : std::vector<std::string>
68 12 : getConversations(const std::string& accountId)
69 : {
70 12 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
71 12 : if (auto* convModule = acc->convModule(true))
72 12 : return convModule->getConversations();
73 0 : return {};
74 : }
75 :
76 : std::vector<std::map<std::string, std::string>>
77 15 : getActiveCalls(const std::string& accountId, const std::string& conversationId)
78 : {
79 15 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
80 15 : if (auto* convModule = acc->convModule(true))
81 15 : return convModule->getActiveCalls(conversationId);
82 0 : return {};
83 : }
84 :
85 : std::vector<std::map<std::string, std::string>>
86 12 : getConversationRequests(const std::string& accountId)
87 : {
88 12 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
89 12 : if (auto* convModule = acc->convModule(true))
90 12 : return convModule->getConversationRequests();
91 0 : return {};
92 : }
93 :
94 : void
95 3 : updateConversationInfos(const std::string& accountId,
96 : const std::string& conversationId,
97 : const std::map<std::string, std::string>& infos)
98 : {
99 3 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
100 3 : if (auto* convModule = acc->convModule(true))
101 3 : convModule->updateConversationInfos(conversationId, infos);
102 3 : }
103 :
104 : std::map<std::string, std::string>
105 5 : conversationInfos(const std::string& accountId, const std::string& conversationId)
106 : {
107 5 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
108 5 : if (auto* convModule = acc->convModule(true))
109 5 : return convModule->conversationInfos(conversationId);
110 0 : return {};
111 : }
112 :
113 : void
114 5 : setConversationPreferences(const std::string& accountId,
115 : const std::string& conversationId,
116 : const std::map<std::string, std::string>& prefs)
117 : {
118 5 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
119 5 : if (auto* convModule = acc->convModule(true))
120 5 : convModule->setConversationPreferences(conversationId, prefs);
121 5 : }
122 :
123 : std::map<std::string, std::string>
124 4 : getConversationPreferences(const std::string& accountId, const std::string& conversationId)
125 : {
126 4 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
127 4 : if (auto* convModule = acc->convModule(true))
128 4 : return convModule->getConversationPreferences(conversationId);
129 0 : return {};
130 : }
131 :
132 : // Member management
133 : void
134 134 : addConversationMember(const std::string& accountId, const std::string& conversationId, const std::string& contactUri)
135 : {
136 134 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
137 134 : if (auto* convModule = acc->convModule(true)) {
138 134 : dht::InfoHash h(contactUri);
139 134 : if (not h) {
140 0 : JAMI_ERROR("addConversationMember: invalid contact URI `{}`", contactUri);
141 0 : return;
142 : }
143 134 : convModule->addConversationMember(conversationId, h);
144 134 : }
145 : }
146 :
147 : void
148 13 : removeConversationMember(const std::string& accountId, const std::string& conversationId, const std::string& contactUri)
149 : {
150 13 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
151 13 : if (auto* convModule = acc->convModule(true)) {
152 13 : dht::InfoHash h(contactUri);
153 13 : if (not h) {
154 0 : JAMI_ERROR("removeConversationMember: invalid contact URI `{}`", contactUri);
155 0 : return;
156 : }
157 13 : convModule->removeConversationMember(conversationId, h);
158 13 : }
159 : }
160 :
161 : std::vector<std::map<std::string, std::string>>
162 22 : getConversationMembers(const std::string& accountId, const std::string& conversationId)
163 : {
164 22 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
165 22 : if (auto* convModule = acc->convModule(true))
166 22 : return convModule->getConversationMembers(conversationId, true);
167 0 : return {};
168 : }
169 :
170 : // Message send/load
171 : void
172 96 : sendMessage(const std::string& accountId,
173 : const std::string& conversationId,
174 : const std::string& message,
175 : const std::string& commitId,
176 : const int32_t& flag)
177 : {
178 96 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
179 96 : if (auto* convModule = acc->convModule(true)) {
180 96 : if (flag == 0 /* Reply or simple commit */) {
181 86 : convModule->sendMessage(conversationId, message, commitId);
182 10 : } else if (flag == 1 /* message edition */) {
183 7 : convModule->editMessage(conversationId, message, commitId);
184 3 : } else if (flag == 2 /* reaction */) {
185 3 : convModule->reactToMessage(conversationId, message, commitId);
186 : }
187 96 : }
188 96 : }
189 :
190 : uint32_t
191 2 : loadConversation(const std::string& accountId,
192 : const std::string& conversationId,
193 : const std::string& fromMessage,
194 : size_t n)
195 : {
196 2 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
197 2 : if (auto* convModule = acc->convModule(true))
198 2 : return convModule->loadConversation(conversationId, fromMessage, n);
199 0 : return 0;
200 : }
201 :
202 : uint32_t
203 0 : loadSwarmUntil(const std::string& accountId,
204 : const std::string& conversationId,
205 : const std::string& fromMessage,
206 : const std::string& toMessage)
207 : {
208 0 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
209 0 : if (auto* convModule = acc->convModule(true))
210 0 : return convModule->loadSwarmUntil(conversationId, fromMessage, toMessage);
211 0 : return 0;
212 : }
213 :
214 : uint32_t
215 4 : countInteractions(const std::string& accountId,
216 : const std::string& conversationId,
217 : const std::string& toId,
218 : const std::string& fromId,
219 : const std::string& authorUri)
220 : {
221 4 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
222 4 : if (auto* convModule = acc->convModule(true))
223 4 : return convModule->countInteractions(conversationId, toId, fromId, authorUri);
224 0 : return 0;
225 : }
226 :
227 : void
228 0 : clearCache(const std::string& accountId, const std::string& conversationId)
229 : {
230 0 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
231 0 : if (auto* convModule = acc->convModule(true))
232 0 : convModule->clearCache(conversationId);
233 0 : }
234 :
235 : uint32_t
236 4 : searchConversation(const std::string& accountId,
237 : const std::string& conversationId,
238 : const std::string& author,
239 : const std::string& lastId,
240 : const std::string& regexSearch,
241 : const std::string& type,
242 : const int64_t& after,
243 : const int64_t& before,
244 : const uint32_t& maxResult,
245 : const int32_t& flag)
246 : {
247 4 : uint32_t res = 0;
248 4 : jami::Filter filter {author, lastId, regexSearch, type, after, before, maxResult, flag != 0};
249 16 : for (const auto& accId : jami::Manager::instance().getAccountList()) {
250 12 : if (!accountId.empty() && accId != accountId)
251 8 : continue;
252 4 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accId)) {
253 4 : res = std::uniform_int_distribution<uint32_t>()(acc->rand);
254 4 : if (auto* convModule = acc->convModule(true)) {
255 4 : convModule->search(res, conversationId, filter);
256 : }
257 4 : }
258 4 : }
259 4 : return res;
260 4 : }
261 :
262 : void
263 0 : reloadConversationsAndRequests(const std::string& accountId)
264 : {
265 0 : if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) {
266 0 : acc->reloadContacts();
267 0 : if (auto* convModule = acc->convModule(true)) {
268 0 : convModule->reloadRequests();
269 0 : convModule->loadConversations();
270 : }
271 0 : }
272 0 : }
273 :
274 : } // namespace libjami
|