LCOV - code coverage report
Current view: top level - src/jamidht - typers.cpp (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 51 51 100.0 %
Date: 2024-12-21 08:56:24 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /*
       2             :  *  Copyright (C) 2004-2024 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             : #include "typers.h"
      19             : #include "manager.h"
      20             : #include "jamidht/jamiaccount.h"
      21             : 
      22             : static constexpr std::chrono::steady_clock::duration COMPOSING_TIMEOUT {std::chrono::seconds(12)};
      23             : 
      24             : namespace jami {
      25             : 
      26         383 : Typers::Typers(const std::shared_ptr<JamiAccount>& acc, const std::string& convId)
      27         383 :     : ioContext_(Manager::instance().ioContext())
      28         383 :     , acc_(acc)
      29         383 :     , accountId_(acc->getAccountID())
      30         383 :     , convId_(convId)
      31        1149 :     , selfUri_(acc->getUsername())
      32             : {
      33             : 
      34         383 : }
      35             : 
      36         383 : Typers::~Typers()
      37             : {
      38         384 :     for (auto& watcher : watcher_) {
      39           1 :         watcher.second.cancel();
      40             :     }
      41         383 :     watcher_.clear();
      42         383 : }
      43             : 
      44             : std::string
      45           4 : getIsComposing(const std::string& conversationId, bool isWriting)
      46             : {
      47             :     // implementing https://tools.ietf.org/rfc/rfc3994.txt
      48             :     return fmt::format("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
      49             :                        "<isComposing><state>{}</state>{}</isComposing>",
      50           4 :                        isWriting ? "active"sv : "idle"sv,
      51           4 :                        conversationId.empty()
      52          12 :                            ? ""
      53          12 :                            : "<conversation>" + conversationId + "</conversation>");
      54             : }
      55             : 
      56             : void
      57           7 : Typers::addTyper(const std::string &typer, bool sendMessage)
      58             : {
      59           7 :     auto acc = acc_.lock();
      60           7 :     if (!acc || !acc->isComposingEnabled())
      61           1 :         return;
      62           6 :     auto [it, res] = watcher_.emplace(typer, asio::steady_timer {*ioContext_});
      63           6 :     if (res) {
      64           6 :         auto& watcher = it->second;
      65             :         // Check next member
      66           6 :         watcher.expires_at(std::chrono::steady_clock::now() + COMPOSING_TIMEOUT);
      67           6 :         watcher.async_wait(
      68          12 :             std::bind(&Typers::onTyperTimeout,
      69          12 :                         shared_from_this(),
      70             :                         std::placeholders::_1,
      71             :                         typer));
      72             : 
      73           6 :         if (typer != selfUri_)
      74           6 :             emitSignal<libjami::ConfigurationSignal::ComposingStatusChanged>(accountId_,
      75           3 :                                                                                 convId_,
      76             :                                                                                 typer,
      77             :                                                                                 1);
      78             :     }
      79           6 :     if (sendMessage) {
      80             :         // In this case we should emit for remote to update the timer
      81           9 :         acc->sendInstantMessage(convId_,
      82           6 :                                {{MIME_TYPE_IM_COMPOSING, getIsComposing(convId_, true)}});
      83             :     }
      84           7 : }
      85             : 
      86             : void
      87          25 : Typers::removeTyper(const std::string &typer, bool sendMessage)
      88             : {
      89          25 :     auto acc = acc_.lock();
      90          25 :     if (!acc || !acc->isComposingEnabled())
      91           1 :         return;
      92          24 :     if (watcher_.erase(typer)) {
      93           5 :         if (sendMessage) {
      94           3 :             acc->sendInstantMessage(convId_,
      95           2 :                                 {{MIME_TYPE_IM_COMPOSING, getIsComposing(convId_, false)}});
      96             :         }
      97           5 :         if (typer != selfUri_) {
      98           6 :             emitSignal<libjami::ConfigurationSignal::ComposingStatusChanged>(accountId_,
      99           3 :                                                                                 convId_,
     100             :                                                                                 typer,
     101             :                                                                                 0);
     102             :         }
     103             :     }
     104          25 : }
     105             : 
     106             : void
     107           6 : Typers::onTyperTimeout(const asio::error_code& ec, const std::string &typer)
     108             : {
     109           6 :     if (ec == asio::error::operation_aborted)
     110           3 :         return;
     111           3 :     removeTyper(typer);
     112             : }
     113             : 
     114             : } // namespace jami

Generated by: LCOV version 1.14