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-05-01 08:46:49 Functions: 6 6 100.0 %

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

Generated by: LCOV version 1.14