LCOV - code coverage report
Current view: top level - foo/src/jamidht - typers.cpp (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 43 43 100.0 %
Date: 2025-12-18 10:07:43 Functions: 6 6 100.0 %

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

Generated by: LCOV version 1.14