LCOV - code coverage report
Current view: top level - src/client - conversation_interface.cpp (source / functions) Coverage Total Hit
Test: jami-coverage-filtered.info Lines: 78.0 % 200 156
Test Date: 2026-11-09 10:41:14 Functions: 92.1 % 38 35

            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/commit_message.h"
      30              : #include "jamidht/jamiaccount.h"
      31              : #include "jamidht/collaborative_editing.h"
      32              : #include "jamidht/conversation_module.h"
      33              : 
      34              : namespace libjami {
      35              : 
      36              : std::string
      37          156 : startConversation(const std::string& accountId)
      38              : {
      39          156 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
      40          156 :         if (auto* convModule = acc->convModule(true))
      41          156 :             return convModule->startConversation();
      42            0 :     return {};
      43              : }
      44              : 
      45              : std::string
      46            1 : startFeedConversation(const std::string& accountId)
      47              : {
      48            1 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
      49            1 :         if (auto* convModule = acc->convModule(true))
      50            1 :             return convModule->startConversation(jami::ConversationMode::FEED);
      51            0 :     return {};
      52              : }
      53              : 
      54              : void
      55          169 : acceptConversationRequest(const std::string& accountId, const std::string& conversationId)
      56              : {
      57          169 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
      58          169 :         if (auto* convModule = acc->convModule(true))
      59          507 :             convModule->acceptConversationRequest(conversationId);
      60          169 : }
      61              : 
      62              : void
      63            3 : declineConversationRequest(const std::string& accountId, const std::string& conversationId)
      64              : {
      65            3 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
      66            3 :         acc->declineConversationRequest(conversationId);
      67            3 : }
      68              : 
      69              : bool
      70           15 : removeConversation(const std::string& accountId, const std::string& conversationId)
      71              : {
      72           15 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
      73           15 :         if (auto* convModule = acc->convModule(true))
      74           15 :             return convModule->removeConversation(conversationId);
      75            0 :     return false;
      76              : }
      77              : 
      78              : std::vector<std::string>
      79           52 : getConversations(const std::string& accountId)
      80              : {
      81           52 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
      82           52 :         if (auto* convModule = acc->convModule(true))
      83           52 :             return convModule->getConversations();
      84            5 :     return {};
      85              : }
      86              : 
      87              : std::vector<std::map<std::string, std::string>>
      88           20 : getActiveCalls(const std::string& accountId, const std::string& conversationId)
      89              : {
      90           20 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
      91           20 :         if (auto* convModule = acc->convModule(true))
      92           20 :             return convModule->getActiveCalls(conversationId);
      93            0 :     return {};
      94              : }
      95              : 
      96              : std::vector<std::map<std::string, std::string>>
      97           95 : getConversationRequests(const std::string& accountId)
      98              : {
      99           95 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     100           95 :         if (auto* convModule = acc->convModule(true))
     101           95 :             return convModule->getConversationRequests();
     102            0 :     return {};
     103              : }
     104              : 
     105              : void
     106            3 : updateConversationInfos(const std::string& accountId,
     107              :                         const std::string& conversationId,
     108              :                         const std::map<std::string, std::string>& infos)
     109              : {
     110            3 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     111            3 :         if (auto* convModule = acc->convModule(true))
     112            3 :             convModule->updateConversationInfos(conversationId, infos);
     113            3 : }
     114              : 
     115              : std::map<std::string, std::string>
     116            5 : conversationInfos(const std::string& accountId, const std::string& conversationId)
     117              : {
     118            5 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     119            5 :         if (auto* convModule = acc->convModule(true))
     120            5 :             return convModule->conversationInfos(conversationId);
     121            0 :     return {};
     122              : }
     123              : 
     124              : void
     125            5 : setConversationPreferences(const std::string& accountId,
     126              :                            const std::string& conversationId,
     127              :                            const std::map<std::string, std::string>& prefs)
     128              : {
     129            5 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     130            5 :         if (auto* convModule = acc->convModule(true))
     131            5 :             convModule->setConversationPreferences(conversationId, prefs);
     132            5 : }
     133              : 
     134              : std::map<std::string, std::string>
     135            4 : getConversationPreferences(const std::string& accountId, const std::string& conversationId)
     136              : {
     137            4 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     138            4 :         if (auto* convModule = acc->convModule(true))
     139            4 :             return convModule->getConversationPreferences(conversationId);
     140            0 :     return {};
     141              : }
     142              : 
     143              : // Member management
     144              : void
     145          174 : addConversationMember(const std::string& accountId, const std::string& conversationId, const std::string& contactUri)
     146              : {
     147          174 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     148          174 :         if (auto* convModule = acc->convModule(true)) {
     149          174 :             dht::InfoHash h(contactUri);
     150          174 :             if (not h) {
     151            0 :                 JAMI_ERROR("addConversationMember: invalid contact URI `{}`", contactUri);
     152            0 :                 return;
     153              :             }
     154          174 :             convModule->addConversationMember(conversationId, h);
     155          174 :         }
     156              : }
     157              : 
     158              : void
     159           14 : removeConversationMember(const std::string& accountId, const std::string& conversationId, const std::string& contactUri)
     160              : {
     161           14 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     162           14 :         if (auto* convModule = acc->convModule(true)) {
     163           14 :             dht::InfoHash h(contactUri);
     164           14 :             if (not h) {
     165            0 :                 JAMI_ERROR("removeConversationMember: invalid contact URI `{}`", contactUri);
     166            0 :                 return;
     167              :             }
     168           14 :             convModule->removeConversationMember(conversationId, h);
     169           14 :         }
     170              : }
     171              : 
     172              : std::vector<std::map<std::string, std::string>>
     173           26 : getConversationMembers(const std::string& accountId, const std::string& conversationId)
     174              : {
     175           26 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     176           26 :         if (auto* convModule = acc->convModule(true))
     177           26 :             return convModule->getConversationMembers(conversationId, true);
     178            0 :     return {};
     179              : }
     180              : 
     181              : std::vector<std::string>
     182            2 : getConversationPermissions(const std::string& accountId, const std::string& conversationId)
     183              : {
     184            2 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     185            2 :         if (auto* convModule = acc->convModule(true))
     186            2 :             return convModule->getConversationPermissions(conversationId);
     187            0 :     return {};
     188              : }
     189              : 
     190              : // Message send/load
     191              : void
     192           98 : sendMessage(const std::string& accountId,
     193              :             const std::string& conversationId,
     194              :             const std::string& message,
     195              :             const std::string& commitId,
     196              :             const int32_t& flag)
     197              : {
     198           98 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     199           98 :         if (auto* convModule = acc->convModule(true)) {
     200           98 :             if (flag == 0 /* Reply or simple commit */) {
     201           89 :                 convModule->sendMessage(conversationId, message, commitId);
     202            9 :             } else if (flag == 1 /* message edition */) {
     203            6 :                 convModule->editMessage(conversationId, message, commitId);
     204            3 :             } else if (flag == 2 /* reaction */) {
     205            3 :                 convModule->reactToMessage(conversationId, message, commitId);
     206              :             }
     207           98 :         }
     208           98 : }
     209              : 
     210              : uint32_t
     211            3 : loadConversation(const std::string& accountId,
     212              :                  const std::string& conversationId,
     213              :                  const std::string& fromMessage,
     214              :                  size_t n)
     215              : {
     216            3 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     217            3 :         if (auto* convModule = acc->convModule(true))
     218            3 :             return convModule->loadConversation(conversationId, fromMessage, n);
     219            0 :     return 0;
     220              : }
     221              : 
     222              : uint32_t
     223            0 : loadSwarmUntil(const std::string& accountId,
     224              :                const std::string& conversationId,
     225              :                const std::string& fromMessage,
     226              :                const std::string& toMessage)
     227              : {
     228            0 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     229            0 :         if (auto* convModule = acc->convModule(true))
     230            0 :             return convModule->loadSwarmUntil(conversationId, fromMessage, toMessage);
     231            0 :     return 0;
     232              : }
     233              : 
     234              : uint32_t
     235            4 : countInteractions(const std::string& accountId,
     236              :                   const std::string& conversationId,
     237              :                   const std::string& toId,
     238              :                   const std::string& fromId,
     239              :                   const std::string& authorUri)
     240              : {
     241            4 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     242            4 :         if (auto* convModule = acc->convModule(true))
     243            4 :             return convModule->countInteractions(conversationId, toId, fromId, authorUri);
     244            0 :     return 0;
     245              : }
     246              : 
     247              : void
     248            0 : clearCache(const std::string& accountId, const std::string& conversationId)
     249              : {
     250            0 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     251            0 :         if (auto* convModule = acc->convModule(true))
     252            0 :             convModule->clearCache(conversationId);
     253            0 : }
     254              : 
     255              : uint32_t
     256            4 : searchConversation(const std::string& accountId,
     257              :                    const std::string& conversationId,
     258              :                    const std::string& author,
     259              :                    const std::string& lastId,
     260              :                    const std::string& regexSearch,
     261              :                    const std::string& type,
     262              :                    const int64_t& after,
     263              :                    const int64_t& before,
     264              :                    const uint32_t& maxResult,
     265              :                    const int32_t& flag)
     266              : {
     267            4 :     uint32_t res = 0;
     268            4 :     jami::Filter filter {author, lastId, regexSearch, type, after, before, maxResult, flag != 0};
     269           16 :     for (const auto& accId : jami::Manager::instance().getAccountList()) {
     270           12 :         if (!accountId.empty() && accId != accountId)
     271            8 :             continue;
     272            4 :         if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accId)) {
     273            4 :             res = std::uniform_int_distribution<uint32_t>()(acc->rand);
     274            4 :             if (auto* convModule = acc->convModule(true)) {
     275            4 :                 convModule->search(res, conversationId, filter);
     276              :             }
     277            4 :         }
     278            4 :     }
     279            4 :     return res;
     280            4 : }
     281              : 
     282              : void
     283            0 : reloadConversationsAndRequests(const std::string& accountId)
     284              : {
     285            0 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId)) {
     286            0 :         acc->reloadContacts();
     287            0 :         if (auto* convModule = acc->convModule(true)) {
     288            0 :             convModule->reloadRequests();
     289            0 :             convModule->loadConversations();
     290              :         }
     291            0 :     }
     292            0 : }
     293              : 
     294              : std::string
     295           25 : createCollaborativeDocument(const std::string& accountId,
     296              :                             const std::string& conversationId,
     297              :                             const std::string& name,
     298              :                             const std::string& mimeType)
     299              : {
     300           25 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     301           25 :         return acc->collaborativeEditing()->createDocument(conversationId, name, mimeType);
     302            0 :     return {};
     303              : }
     304              : 
     305              : std::vector<uint8_t>
     306           24 : openCollaborativeDocument(const std::string& accountId, const std::string& conversationId, const std::string& documentId)
     307              : {
     308           24 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     309           24 :         return acc->collaborativeEditing()->openDocument(conversationId, documentId);
     310            0 :     return {};
     311              : }
     312              : 
     313              : bool
     314            1 : removeCollaborativeDocument(const std::string& accountId,
     315              :                             const std::string& conversationId,
     316              :                             const std::string& documentId)
     317              : {
     318            1 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     319            1 :         return acc->collaborativeEditing()->removeDocument(conversationId, documentId);
     320            0 :     return false;
     321              : }
     322              : 
     323              : bool
     324            4 : removeCollaborativeDocumentLocally(const std::string& accountId,
     325              :                                    const std::string& conversationId,
     326              :                                    const std::string& documentId)
     327              : {
     328            4 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     329            4 :         return acc->collaborativeEditing()->removeDocumentLocally(conversationId, documentId);
     330            0 :     return false;
     331              : }
     332              : 
     333              : void
     334           15 : closeCollaborativeDocument(const std::string& accountId,
     335              :                            const std::string& conversationId,
     336              :                            const std::string& documentId)
     337              : {
     338           15 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     339           15 :         acc->collaborativeEditing()->closeDocument(conversationId, documentId);
     340           15 : }
     341              : 
     342              : void
     343           13 : applyCollaborativeUpdate(const std::string& accountId,
     344              :                          const std::string& conversationId,
     345              :                          const std::string& documentId,
     346              :                          const std::vector<uint8_t>& update)
     347              : {
     348           13 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     349           13 :         acc->collaborativeEditing()->applyUpdate(conversationId, documentId, update);
     350           13 : }
     351              : 
     352              : void
     353            1 : setCollaborativeAwareness(const std::string& accountId,
     354              :                           const std::string& conversationId,
     355              :                           const std::string& documentId,
     356              :                           const std::string& state)
     357              : {
     358            1 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     359            1 :         acc->collaborativeEditing()->setAwareness(conversationId, documentId, state);
     360            1 : }
     361              : 
     362              : std::vector<uint8_t>
     363            7 : collaborativeDocumentState(const std::string& accountId,
     364              :                            const std::string& conversationId,
     365              :                            const std::string& documentId)
     366              : {
     367            7 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     368            7 :         return acc->collaborativeEditing()->documentState(conversationId, documentId);
     369            0 :     return {};
     370              : }
     371              : 
     372              : void
     373            2 : setCollaborativeDocumentName(const std::string& accountId,
     374              :                              const std::string& conversationId,
     375              :                              const std::string& documentId,
     376              :                              const std::string& name)
     377              : {
     378            2 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     379            2 :         acc->collaborativeEditing()->setName(conversationId, documentId, name);
     380            2 : }
     381              : 
     382              : std::string
     383            2 : collaborativeDocumentName(const std::string& accountId, const std::string& conversationId, const std::string& documentId)
     384              : {
     385            2 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     386            2 :         return acc->collaborativeEditing()->documentName(conversationId, documentId);
     387            0 :     return {};
     388              : }
     389              : 
     390              : std::vector<std::map<std::string, std::string>>
     391           97 : getCollaborativeDocuments(const std::string& accountId, const std::string& conversationId)
     392              : {
     393           97 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     394           97 :         return acc->collaborativeEditing()->documents(conversationId);
     395            0 :     return {};
     396              : }
     397              : 
     398              : std::vector<std::map<std::string, std::string>>
     399          105 : getCollaborativeDocumentHistory(const std::string& accountId,
     400              :                                 const std::string& conversationId,
     401              :                                 const std::string& documentId,
     402              :                                 uint32_t max)
     403              : {
     404          105 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     405          105 :         return acc->collaborativeEditing()->history(conversationId, documentId, max);
     406            0 :     return {};
     407              : }
     408              : 
     409              : std::vector<uint8_t>
     410            3 : collaborativeDocumentStateAt(const std::string& accountId,
     411              :                              const std::string& conversationId,
     412              :                              const std::string& documentId,
     413              :                              const std::string& commitId)
     414              : {
     415            3 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     416            3 :         return acc->collaborativeEditing()->documentStateAt(conversationId, documentId, commitId);
     417            0 :     return {};
     418              : }
     419              : 
     420              : std::string
     421            1 : addCollaborativeAttachment(const std::string& accountId,
     422              :                            const std::string& conversationId,
     423              :                            const std::string& documentId,
     424              :                            const std::vector<uint8_t>& data)
     425              : {
     426            1 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     427            1 :         return acc->collaborativeEditing()->addAttachment(conversationId, documentId, data);
     428            0 :     return {};
     429              : }
     430              : 
     431              : std::vector<uint8_t>
     432            3 : collaborativeAttachment(const std::string& accountId,
     433              :                         const std::string& conversationId,
     434              :                         const std::string& documentId,
     435              :                         const std::string& attachmentId)
     436              : {
     437            3 :     if (auto acc = jami::Manager::instance().getAccount<jami::JamiAccount>(accountId))
     438            3 :         return acc->collaborativeEditing()->attachment(conversationId, documentId, attachmentId);
     439            0 :     return {};
     440              : }
     441              : 
     442              : } // namespace libjami
        

Generated by: LCOV version 2.0-1