LCOV - code coverage report
Current view: top level - src/client - conversation_interface.cpp (source / functions) Coverage Total Hit
Test: jami-coverage-filtered.info Lines: 76.3 % 190 145
Test Date: 2026-08-23 08:52:56 Functions: 88.9 % 36 32

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

Generated by: LCOV version 2.0-1