mirror of
https://git.jami.net/savoirfairelinux/jami-daemon.git
synced 2025-08-12 22:09:25 +08:00
swarm: relink setMessageDisplayed
Change-Id: Ic1e002a1e8edf79c5c392e707dd857c7e88667ec GitLab: #319
This commit is contained in:
@ -584,13 +584,14 @@
|
||||
</signal>
|
||||
|
||||
<signal name="accountMessageStatusChanged" tp:name-for-bindings="accountMessageStatusChanged">
|
||||
<tp:added version="2.3.0"/>
|
||||
<tp:added version="10.0.0"/>
|
||||
<tp:docstring>
|
||||
Notify clients that a sent text message status have changed
|
||||
</tp:docstring>
|
||||
<arg type="s" name="accountID"/>
|
||||
<arg type="t" name="id"/>
|
||||
<arg type="s" name="to"/>
|
||||
<arg type="s" name="id"/>
|
||||
<arg type="s" name="conversationId"/>
|
||||
<arg type="s" name="peer"/>
|
||||
<arg type="i" name="status">
|
||||
<tp:docstring>The new status of the message, see getMessageStatus for possible values.</tp:docstring>
|
||||
</arg>
|
||||
@ -640,9 +641,9 @@
|
||||
The account ID
|
||||
</tp:docstring>
|
||||
</arg>
|
||||
<arg type="s" name="contactId" direction="in">
|
||||
<arg type="s" name="conversationUri" direction="in">
|
||||
<tp:docstring>
|
||||
The contact ID
|
||||
A conversation uri (swarm:xxxx or jami:xxxx)
|
||||
</tp:docstring>
|
||||
</arg>
|
||||
<arg type="s" name="messageId" direction="in">
|
||||
|
@ -224,7 +224,7 @@ DBusClient::initLibrary(int flags)
|
||||
exportable_callback<ConfigurationSignal::IncomingAccountMessage>(
|
||||
bind(&DBusConfigurationManager::incomingAccountMessage, confM, _1, _2, _3, _4)),
|
||||
exportable_callback<ConfigurationSignal::AccountMessageStatusChanged>(
|
||||
bind(&DBusConfigurationManager::accountMessageStatusChanged, confM, _1, _2, _3, _4)),
|
||||
bind(&DBusConfigurationManager::accountMessageStatusChanged, confM, _1, _2, _3, _4, _5)),
|
||||
exportable_callback<ConfigurationSignal::ProfileReceived>(
|
||||
bind(&DBusConfigurationManager::profileReceived, confM, _1, _2, _3)),
|
||||
exportable_callback<ConfigurationSignal::ComposingStatusChanged>(
|
||||
|
@ -234,11 +234,11 @@ DBusConfigurationManager::setIsComposing(const std::string& accountID,
|
||||
|
||||
bool
|
||||
DBusConfigurationManager::setMessageDisplayed(const std::string& accountID,
|
||||
const std::string& contactId,
|
||||
const std::string& conversationUri,
|
||||
const std::string& messageId,
|
||||
const int32_t& status)
|
||||
{
|
||||
return DRing::setMessageDisplayed(accountID, contactId, messageId, status);
|
||||
return DRing::setMessageDisplayed(accountID, conversationUri, messageId, status);
|
||||
}
|
||||
|
||||
auto
|
||||
|
@ -97,7 +97,7 @@ public:
|
||||
int getMessageStatus(const std::string& accountID, const uint64_t& id);
|
||||
bool cancelMessage(const std::string& accountID, const uint64_t& messageId);
|
||||
void setIsComposing(const std::string& accountID, const std::string& to, const bool& isWriting);
|
||||
bool setMessageDisplayed(const std::string& accountID, const std::string& contactId, const std::string& messageId, const int32_t& status);
|
||||
bool setMessageDisplayed(const std::string& accountID, const std::string& conversationUri, const std::string& messageId, const int32_t& status);
|
||||
std::vector<std::string> getSupportedCiphers(const std::string& accountID);
|
||||
std::vector<unsigned> getCodecList();
|
||||
std::vector<std::string> getSupportedTlsMethod();
|
||||
|
@ -34,7 +34,7 @@ public:
|
||||
virtual void registrationStateChanged(const std::string& account_id, const std::string& state, int code, const std::string& detail_str){}
|
||||
virtual void volatileAccountDetailsChanged(const std::string& account_id, const std::map<std::string, std::string>& details){}
|
||||
virtual void incomingAccountMessage(const std::string& /*account_id*/, const std::string& /*message_id*/, const std::string& /*from*/, const std::map<std::string, std::string>& /*payload*/){}
|
||||
virtual void accountMessageStatusChanged(const std::string& /*account_id*/, uint64_t /*message_id*/, const std::string& /*to*/, int /*state*/){}
|
||||
virtual void accountMessageStatusChanged(const std::string& /*account_id*/, const std::string& /*message_id*/, const std::string& /*conversationId*/, const std::string& /*peer*/, int /*state*/){}
|
||||
virtual void profileReceived(const std::string& /*account_id*/, const std::string& /*from*/, const std::string& /*path*/){}
|
||||
virtual void composingStatusChanged(const std::string& /*account_id*/, const std::string& /*convId*/, const std::string& /*from*/, int /*state*/){}
|
||||
virtual void knownDevicesChanged(const std::string& /*account_id*/, const std::map<std::string, std::string>& /*devices*/){}
|
||||
@ -99,7 +99,7 @@ int getMessageStatus(uint64_t id);
|
||||
int getMessageStatus(const std::string& accountID, uint64_t id);
|
||||
bool cancelMessage(const std::string& accountID, uint64_t id);
|
||||
void setIsComposing(const std::string& accountID, const std::string& to, bool isWriting);
|
||||
bool setMessageDisplayed(const std::string& accountID, const std::string& contactId, const std::string& messageId, int status);
|
||||
bool setMessageDisplayed(const std::string& accountID, const std::string& conversationUri, const std::string& messageId, int status);
|
||||
bool changeAccountPassword(const std::string& accountID, const std::string& password_old, const std::string& password_new);
|
||||
|
||||
bool lookupName(const std::string& account, const std::string& nameserver, const std::string& name);
|
||||
@ -250,7 +250,7 @@ public:
|
||||
virtual void registrationStateChanged(const std::string& account_id, const std::string& state, int code, const std::string& detail_str){}
|
||||
virtual void volatileAccountDetailsChanged(const std::string& account_id, const std::map<std::string, std::string>& details){}
|
||||
virtual void incomingAccountMessage(const std::string& /*account_id*/, const std::string& /*message_id*/, const std::string& /*from*/, const std::map<std::string, std::string>& /*payload*/){}
|
||||
virtual void accountMessageStatusChanged(const std::string& /*account_id*/, uint64_t /*message_id*/, const std::string& /*to*/, int /*state*/){}
|
||||
virtual void accountMessageStatusChanged(const std::string& /*account_id*/, const std::string& /*message_id*/, const std::string& /*conversationId*/, const std::string& /*peer*/, int /*state*/){}
|
||||
virtual void composingStatusChanged(const std::string& /*account_id*/, const std::string& /*convId*/, const std::string& /*from*/, int /*state*/){}
|
||||
virtual void knownDevicesChanged(const std::string& /*account_id*/, const std::map<std::string, std::string>& /*devices*/){}
|
||||
virtual void exportOnRingEnded(const std::string& /*account_id*/, int /*state*/, const std::string& /*pin*/){}
|
||||
|
@ -270,7 +270,7 @@ void init(ConfigurationCallback* confM, Callback* callM, PresenceCallback* presM
|
||||
exportable_callback<ConfigurationSignal::ExportOnRingEnded>(bind(&ConfigurationCallback::exportOnRingEnded, confM, _1, _2, _3)),
|
||||
exportable_callback<ConfigurationSignal::Error>(bind(&ConfigurationCallback::errorAlert, confM, _1)),
|
||||
exportable_callback<ConfigurationSignal::IncomingAccountMessage>(bind(&ConfigurationCallback::incomingAccountMessage, confM, _1, _2, _3, _4 )),
|
||||
exportable_callback<ConfigurationSignal::AccountMessageStatusChanged>(bind(&ConfigurationCallback::accountMessageStatusChanged, confM, _1, _2, _3, _4 )),
|
||||
exportable_callback<ConfigurationSignal::AccountMessageStatusChanged>(bind(&ConfigurationCallback::accountMessageStatusChanged, confM, _1, _2, _3, _4, _5 )),
|
||||
exportable_callback<ConfigurationSignal::ProfileReceived>(bind(&ConfigurationCallback::profileReceived, confM, _1, _2, _3 )),
|
||||
exportable_callback<ConfigurationSignal::ComposingStatusChanged>(bind(&ConfigurationCallback::composingStatusChanged, confM, _1, _2, _3, _4 )),
|
||||
exportable_callback<ConfigurationSignal::IncomingTrustRequest>(bind(&ConfigurationCallback::incomingTrustRequest, confM, _1, _2, _3, _4 )),
|
||||
|
@ -330,10 +330,10 @@ registeredNameFound(const std::string& accountId,
|
||||
uv_async_send(&signalAsync);
|
||||
}
|
||||
|
||||
void accountMessageStatusChanged(const std::string& account_id, uint64_t message_id, const std::string& to, int state) {
|
||||
void accountMessageStatusChanged(const std::string& account_id, const std::string& message_id, const std::string& conversationId, const std::string& peer, int state) {
|
||||
|
||||
std::lock_guard<std::mutex> lock(pendingSignalsLock);
|
||||
pendingSignals.emplace([account_id, message_id, to, state]() {
|
||||
pendingSignals.emplace([account_id, message_id, peer, state]() {
|
||||
Local<Function> func = Local<Function>::New(Isolate::GetCurrent(), accountMessageStatusChangedCb);
|
||||
if (!func.IsEmpty()) {
|
||||
Local<Value> callback_args[] = {V8_STRING_NEW_LOCAL(account_id), SWIGV8_INTEGER_NEW_UNS(message_id), V8_STRING_NEW_LOCAL(to), SWIGV8_INTEGER_NEW(state)};
|
||||
|
@ -33,7 +33,8 @@ public:
|
||||
virtual void registrationStateChanged(const std::string& account_id, const std::string& state, int code, const std::string& detail_str){}
|
||||
virtual void volatileAccountDetailsChanged(const std::string& account_id, const std::map<std::string, std::string>& details){}
|
||||
virtual void incomingAccountMessage(const std::string& /*account_id*/, const std::string& /*from*/, const std::map<std::string, std::string>& /*payload*/){}
|
||||
virtual void accountMessageStatusChanged(const std::string& /*account_id*/, uint64_t /*message_id*/, const std::string& /*to*/, int /*state*/){}
|
||||
virtual void accountMessageStatusChanged(const std::string& /*account_id*/, const std::string& /*message_id*/, const std::string& /*conversationId*/, const std::string& /*peer*/, int /*state*/){}
|
||||
virtual void profileReceived(const std::string& /*account_id*/, const std::string& /*from*/, const std::string& /*path*/){}
|
||||
virtual void knownDevicesChanged(const std::string& /*account_id*/, const std::map<std::string, std::string>& /*devices*/){}
|
||||
virtual void exportOnRingEnded(const std::string& /*account_id*/, int /*state*/, const std::string& /*pin*/){}
|
||||
|
||||
@ -90,7 +91,7 @@ std::vector<Message> getLastMessages(const std::string& accountID, const uint64_
|
||||
int getMessageStatus(uint64_t id);
|
||||
int getMessageStatus(const std::string& accountID, uint64_t id);
|
||||
bool cancelMessage(const std::string& accountID, uint64_t id);
|
||||
bool setMessageDisplayed(const std::string& accountID, const std::string& contactId, const std::string& messageId, int status);
|
||||
bool setMessageDisplayed(const std::string& accountID, const std::string& conversationUri, const std::string& messageId, int status);
|
||||
bool lookupName(const std::string& account, const std::string& nameserver, const std::string& name);
|
||||
bool lookupAddress(const std::string& account, const std::string& nameserver, const std::string& address);
|
||||
bool registerName(const std::string& account, const std::string& password, const std::string& name);
|
||||
@ -231,7 +232,12 @@ public:
|
||||
virtual void registrationStateChanged(const std::string& account_id, const std::string& state, int code, const std::string& detail_str){}
|
||||
virtual void volatileAccountDetailsChanged(const std::string& account_id, const std::map<std::string, std::string>& details){}
|
||||
virtual void incomingAccountMessage(const std::string& /*account_id*/, const std::string& /*from*/, const std::map<std::string, std::string>& /*payload*/){}
|
||||
<<<<<<< HEAD
|
||||
virtual void accountMessageStatusChanged(const std::string& /*account_id*/, uint64_t /*message_id*/, const std::string& /*to*/, int /*state*/){}
|
||||
=======
|
||||
virtual void accountMessageStatusChanged(const std::string& /*account_id*/, const std::string& /*message_id*/, const std::string& /*conversationId*/, const std::string& /*peer*/, int /*state*/){}
|
||||
virtual void profileReceived(const std::string& /*account_id*/, const std::string& /*from*/, const std::string& /*path*/){}
|
||||
>>>>>>> 503df0a61 (swarm: relink setMessageDisplayed)
|
||||
virtual void knownDevicesChanged(const std::string& /*account_id*/, const std::map<std::string, std::string>& /*devices*/){}
|
||||
virtual void exportOnRingEnded(const std::string& /*account_id*/, int /*state*/, const std::string& /*pin*/){}
|
||||
|
||||
|
@ -139,7 +139,8 @@ void init(const SWIGV8_VALUE& funcMap){
|
||||
exportable_callback<ConfigurationSignal::VolatileDetailsChanged>(bind(&volatileDetailsChanged, _1, _2)),
|
||||
exportable_callback<ConfigurationSignal::KnownDevicesChanged>(bind(&knownDevicesChanged, _1, _2 )),
|
||||
exportable_callback<ConfigurationSignal::IncomingAccountMessage>(bind(&incomingAccountMessage, _1, _2, _3, _4 )),
|
||||
exportable_callback<ConfigurationSignal::AccountMessageStatusChanged>(bind(&accountMessageStatusChanged, _1, _2, _3, _4 )),
|
||||
exportable_callback<ConfigurationSignal::AccountMessageStatusChanged>(bind(&accountMessageStatusChanged, _1, _2, _3, _4, _5 )),
|
||||
exportable_callback<ConfigurationSignal::ProfileReceived>(bind(&profileReceived, _1, _2, _3, _4 )),
|
||||
exportable_callback<ConfigurationSignal::IncomingTrustRequest>(bind(&incomingTrustRequest, _1, _2, _3, _4 )),
|
||||
};
|
||||
|
||||
|
@ -189,6 +189,8 @@ libring_la_SOURCES = \
|
||||
scheduled_executor.h \
|
||||
scheduled_executor.cpp \
|
||||
transport/peer_channel.h \
|
||||
uri.h \
|
||||
uri.cpp \
|
||||
vcard.h
|
||||
|
||||
if HAVE_WIN32
|
||||
|
@ -185,7 +185,7 @@ public:
|
||||
const std::string& /*peer*/,
|
||||
bool /*isWriting*/);
|
||||
|
||||
virtual bool setMessageDisplayed(const std::string& /*contactId*/,
|
||||
virtual bool setMessageDisplayed(const std::string& /*conversationUri*/,
|
||||
const std::string& /*messageId*/,
|
||||
int /*status*/)
|
||||
{
|
||||
|
@ -292,12 +292,12 @@ setIsComposing(const std::string& accountID, const std::string& to, bool isWriti
|
||||
|
||||
bool
|
||||
setMessageDisplayed(const std::string& accountID,
|
||||
const std::string& contactId,
|
||||
const std::string& conversationUri,
|
||||
const std::string& messageId,
|
||||
int status)
|
||||
{
|
||||
if (const auto acc = jami::Manager::instance().getAccount(accountID))
|
||||
return acc->setMessageDisplayed(contactId, messageId, status);
|
||||
return acc->setMessageDisplayed(conversationUri, messageId, status);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ DRING_PUBLIC void setIsComposing(const std::string& accountID,
|
||||
const std::string& to,
|
||||
bool isWriting);
|
||||
DRING_PUBLIC bool setMessageDisplayed(const std::string& accountID,
|
||||
const std::string& contactId,
|
||||
const std::string& conversationUri,
|
||||
const std::string& messageId,
|
||||
int status);
|
||||
|
||||
@ -381,8 +381,9 @@ struct DRING_PUBLIC ConfigurationSignal
|
||||
{
|
||||
constexpr static const char* name = "AccountMessageStatusChanged";
|
||||
using cb_type = void(const std::string& /*account_id*/,
|
||||
uint64_t /*message_id*/,
|
||||
const std::string& /*to*/,
|
||||
const std::string& /*message_id*/,
|
||||
const std::string& /*conversation_id*/,
|
||||
const std::string& /*peer*/,
|
||||
int /*state*/);
|
||||
};
|
||||
struct DRING_PUBLIC ProfileReceived
|
||||
|
@ -102,7 +102,11 @@ MessageEngine::retrySend(const std::string& peer, bool retryOnTimeout)
|
||||
for (const auto& p : pending) {
|
||||
JAMI_DBG() << "[message " << p.token << "] Retry sending";
|
||||
emitSignal<DRing::ConfigurationSignal::AccountMessageStatusChanged>(
|
||||
account_.getAccountID(), p.token, p.to, (int) DRing::Account::MessageStates::SENDING);
|
||||
account_.getAccountID(),
|
||||
"",
|
||||
std::to_string(p.token),
|
||||
p.to,
|
||||
(int) DRing::Account::MessageStates::SENDING);
|
||||
account_.sendTextMessage(p.to, p.payloads, p.token, retryOnTimeout);
|
||||
}
|
||||
}
|
||||
@ -129,7 +133,8 @@ MessageEngine::cancel(MessageToken t)
|
||||
m->second.status = MessageStatus::CANCELLED;
|
||||
emitSignal<DRing::ConfigurationSignal::AccountMessageStatusChanged>(
|
||||
account_.getAccountID(),
|
||||
t,
|
||||
"",
|
||||
std::to_string(t),
|
||||
m->second.to,
|
||||
static_cast<int>(DRing::Account::MessageStates::CANCELLED));
|
||||
save_();
|
||||
@ -157,7 +162,8 @@ MessageEngine::onMessageSent(const std::string& peer, MessageToken token, bool o
|
||||
JAMI_DBG() << "[message " << token << "] Status changed to SENT";
|
||||
emitSignal<DRing::ConfigurationSignal::AccountMessageStatusChanged>(
|
||||
account_.getAccountID(),
|
||||
token,
|
||||
"",
|
||||
std::to_string(token),
|
||||
f->second.to,
|
||||
static_cast<int>(DRing::Account::MessageStates::SENT));
|
||||
save_();
|
||||
@ -166,7 +172,8 @@ MessageEngine::onMessageSent(const std::string& peer, MessageToken token, bool o
|
||||
JAMI_DBG() << "[message " << token << "] Status changed to FAILURE";
|
||||
emitSignal<DRing::ConfigurationSignal::AccountMessageStatusChanged>(
|
||||
account_.getAccountID(),
|
||||
token,
|
||||
"",
|
||||
std::to_string(token),
|
||||
f->second.to,
|
||||
static_cast<int>(DRing::Account::MessageStates::FAILURE));
|
||||
save_();
|
||||
@ -190,7 +197,8 @@ MessageEngine::onMessageDisplayed(const std::string& peer, MessageToken token, b
|
||||
JAMI_DBG() << "[message " << token << "] Displayed by peer";
|
||||
emitSignal<DRing::ConfigurationSignal::AccountMessageStatusChanged>(
|
||||
account_.getAccountID(),
|
||||
token,
|
||||
"", /* No related conversation */
|
||||
std::to_string(token),
|
||||
peer,
|
||||
static_cast<int>(DRing::Account::MessageStates::DISPLAYED));
|
||||
}
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "fileutils.h"
|
||||
#include "sip_utils.h"
|
||||
#include "utf8_utils.h"
|
||||
#include "uri.h"
|
||||
|
||||
#include "manager.h"
|
||||
#ifdef ENABLE_PLUGIN
|
||||
@ -136,15 +137,16 @@ getIsComposing(const std::string& conversationId, bool isWriting)
|
||||
}
|
||||
|
||||
std::string
|
||||
getDisplayed(const std::string& messageId)
|
||||
getDisplayed(const std::string& conversationId, const std::string& messageId)
|
||||
{
|
||||
// implementing https://tools.ietf.org/rfc/rfc5438.txt
|
||||
return fmt::format(
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<imdn><message-id>{}</message-id>\n"
|
||||
"<display-notification><status><displayed/></status></display-notification>\n"
|
||||
"</imdn>",
|
||||
messageId);
|
||||
return fmt::format("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<imdn><message-id>{}</message-id>\n"
|
||||
"{}"
|
||||
"<display-notification><status><displayed/></status></display-notification>\n"
|
||||
"</imdn>",
|
||||
messageId,
|
||||
conversationId.empty()? "" : "<conversation>" + conversationId + "</conversation>");
|
||||
}
|
||||
|
||||
void
|
||||
@ -571,7 +573,28 @@ SIPAccountBase::onTextMessage(const std::string& id,
|
||||
JAMI_WARN("Message displayed: can't parse status");
|
||||
continue;
|
||||
}
|
||||
messageEngine_.onMessageDisplayed(from, from_hex_string(messageId), isDisplayed);
|
||||
|
||||
static const std::regex CONVID_REGEX(
|
||||
"<conversation>\\s*(\\w+)\\s*<\\/conversation>");
|
||||
std::regex_search(m.second, matched_pattern, CONVID_REGEX);
|
||||
std::string conversationId = "";
|
||||
if (matched_pattern.ready() && !matched_pattern.empty()
|
||||
&& matched_pattern[1].matched) {
|
||||
conversationId = matched_pattern[1];
|
||||
}
|
||||
|
||||
if (conversationId.empty()) // Old method
|
||||
messageEngine_.onMessageDisplayed(from, from_hex_string(messageId), isDisplayed);
|
||||
else if (isDisplayed) {
|
||||
JAMI_DBG() << "[message " << messageId << "] Displayed by peer";
|
||||
emitSignal<DRing::ConfigurationSignal::AccountMessageStatusChanged>(
|
||||
accountID_,
|
||||
messageId,
|
||||
conversationId,
|
||||
from,
|
||||
static_cast<int>(DRing::Account::MessageStates::DISPLAYED));
|
||||
return;
|
||||
}
|
||||
if (payloads.size() == 1)
|
||||
return;
|
||||
} catch (const std::exception& e) {
|
||||
@ -637,12 +660,17 @@ SIPAccountBase::onTextMessage(const std::string& id,
|
||||
}
|
||||
|
||||
bool
|
||||
SIPAccountBase::setMessageDisplayed(const std::string& contactId,
|
||||
SIPAccountBase::setMessageDisplayed(const std::string& conversationUri,
|
||||
const std::string& messageId,
|
||||
int status)
|
||||
{
|
||||
Uri uri(conversationUri);
|
||||
std::string conversationId = {};
|
||||
if (uri.scheme() == Uri::Scheme::SWARM)
|
||||
conversationId = uri.authority();
|
||||
if (status == (int) DRing::Account::MessageStates::DISPLAYED)
|
||||
sendTextMessage(contactId, {{MIME_TYPE_IMDN, getDisplayed(messageId)}});
|
||||
sendInstantMessage(uri.authority(),
|
||||
{{MIME_TYPE_IMDN, getDisplayed(conversationId, messageId)}});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -272,7 +272,7 @@ public:
|
||||
|
||||
void setIsComposing(const std::string& to, bool isWriting) override;
|
||||
|
||||
bool setMessageDisplayed(const std::string& contactId,
|
||||
bool setMessageDisplayed(const std::string& conversationUri,
|
||||
const std::string& messageId,
|
||||
int status) override;
|
||||
|
||||
|
79
src/uri.cpp
Normal file
79
src/uri.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Savoir-faire Linux Inc.
|
||||
*
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#include "uri.h"
|
||||
|
||||
namespace jami {
|
||||
|
||||
Uri::Uri(const std::string_view& uri)
|
||||
{
|
||||
// TODO better handling of Uri, for now it's only used for
|
||||
// setMessageDisplayed to differentiate swarm:xxx
|
||||
scheme_ = Uri::Scheme::JAMI;
|
||||
auto posSep = uri.find(':');
|
||||
if (posSep != std::string::npos) {
|
||||
auto scheme_str = uri.substr(0, posSep);
|
||||
if (scheme_str == "sip")
|
||||
scheme_ = Uri::Scheme::SIP;
|
||||
else if (scheme_str == "swarm")
|
||||
scheme_ = Uri::Scheme::SWARM;
|
||||
else if (scheme_str == "jami")
|
||||
scheme_ = Uri::Scheme::JAMI;
|
||||
else
|
||||
scheme_ = Uri::Scheme::UNRECOGNIZED;
|
||||
authority_ = uri.substr(posSep + 1);
|
||||
} else {
|
||||
authority_ = uri;
|
||||
}
|
||||
}
|
||||
|
||||
const std::string&
|
||||
Uri::authority() const
|
||||
{
|
||||
return authority_;
|
||||
}
|
||||
|
||||
Uri::Scheme
|
||||
Uri::scheme() const
|
||||
{
|
||||
return scheme_;
|
||||
}
|
||||
|
||||
std::string
|
||||
Uri::toString() const
|
||||
{
|
||||
return schemeToString() + ":" + authority_;
|
||||
}
|
||||
|
||||
std::string
|
||||
Uri::schemeToString() const
|
||||
{
|
||||
switch (scheme_) {
|
||||
case Uri::Scheme::SIP:
|
||||
return "sip";
|
||||
case Uri::Scheme::SWARM:
|
||||
return "swarm";
|
||||
case Uri::Scheme::JAMI:
|
||||
case Uri::Scheme::UNRECOGNIZED:
|
||||
default:
|
||||
return "jami";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace jami
|
49
src/uri.h
Normal file
49
src/uri.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Savoir-faire Linux Inc.
|
||||
*
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace jami {
|
||||
|
||||
class Uri
|
||||
{
|
||||
public:
|
||||
enum class Scheme {
|
||||
JAMI, // Start with "jami:" and 45 ASCII chars OR 40 ASCII chars
|
||||
SIP, // Start with "sip:"
|
||||
SWARM, // Start with "swarm:" and 40 ASCII chars
|
||||
UNRECOGNIZED // Anything that doesn't fit in other categories
|
||||
};
|
||||
|
||||
Uri(const std::string_view& uri);
|
||||
|
||||
const std::string& authority() const;
|
||||
Scheme scheme() const;
|
||||
std::string toString() const;
|
||||
// TODO hostname, transport, handle sip:
|
||||
|
||||
private:
|
||||
std::string schemeToString() const;
|
||||
Scheme scheme_;
|
||||
std::string authority_;
|
||||
};
|
||||
} // namespace jami
|
@ -109,6 +109,7 @@ private:
|
||||
void testSendMessageToMultipleParticipants();
|
||||
void testPingPongMessages();
|
||||
void testIsComposing();
|
||||
void testSetMessageDisplayed();
|
||||
void testRemoveMember();
|
||||
void testMemberBanNoBadFile();
|
||||
void testMemberTryToRemoveAdmin();
|
||||
@ -170,6 +171,7 @@ private:
|
||||
CPPUNIT_TEST(testSendMessageToMultipleParticipants);
|
||||
CPPUNIT_TEST(testPingPongMessages);
|
||||
CPPUNIT_TEST(testIsComposing);
|
||||
CPPUNIT_TEST(testSetMessageDisplayed);
|
||||
CPPUNIT_TEST(testRemoveMember);
|
||||
CPPUNIT_TEST(testMemberBanNoBadFile);
|
||||
CPPUNIT_TEST(testMemberTryToRemoveAdmin);
|
||||
@ -1169,6 +1171,79 @@ ConversationTest::testIsComposing()
|
||||
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return !aliceComposing; }));
|
||||
}
|
||||
|
||||
void
|
||||
ConversationTest::testSetMessageDisplayed()
|
||||
{
|
||||
auto aliceAccount = Manager::instance().getAccount<JamiAccount>(aliceId);
|
||||
auto bobAccount = Manager::instance().getAccount<JamiAccount>(bobId);
|
||||
auto aliceUri = aliceAccount->getUsername();
|
||||
auto bobUri = bobAccount->getUsername();
|
||||
auto convId = aliceAccount->startConversation();
|
||||
std::mutex mtx;
|
||||
std::unique_lock<std::mutex> lk {mtx};
|
||||
std::condition_variable cv;
|
||||
std::map<std::string, std::shared_ptr<DRing::CallbackWrapperBase>> confHandlers;
|
||||
bool conversationReady = false, requestReceived = false, memberMessageGenerated = false,
|
||||
msgDisplayed = false;
|
||||
confHandlers.insert(
|
||||
DRing::exportable_callback<DRing::ConversationSignal::ConversationRequestReceived>(
|
||||
[&](const std::string& /*accountId*/,
|
||||
const std::string& /* conversationId */,
|
||||
std::map<std::string, std::string> /*metadatas*/) {
|
||||
requestReceived = true;
|
||||
cv.notify_one();
|
||||
}));
|
||||
confHandlers.insert(DRing::exportable_callback<DRing::ConversationSignal::ConversationReady>(
|
||||
[&](const std::string& accountId, const std::string& conversationId) {
|
||||
if (accountId == bobId && conversationId == convId) {
|
||||
conversationReady = true;
|
||||
cv.notify_one();
|
||||
}
|
||||
}));
|
||||
confHandlers.insert(DRing::exportable_callback<DRing::ConversationSignal::MessageReceived>(
|
||||
[&](const std::string& accountId,
|
||||
const std::string& conversationId,
|
||||
std::map<std::string, std::string> message) {
|
||||
if (accountId == aliceId && conversationId == convId && message["type"] == "member") {
|
||||
memberMessageGenerated = true;
|
||||
cv.notify_one();
|
||||
}
|
||||
}));
|
||||
confHandlers.insert(
|
||||
DRing::exportable_callback<DRing::ConfigurationSignal::AccountMessageStatusChanged>(
|
||||
[&](const std::string& accountId,
|
||||
const std::string& msgId,
|
||||
const std::string& conversationId,
|
||||
const std::string& peer,
|
||||
int status) {
|
||||
if (accountId == bobId && conversationId == convId && msgId == conversationId
|
||||
&& peer == aliceUri && status == 3) {
|
||||
msgDisplayed = true;
|
||||
cv.notify_one();
|
||||
}
|
||||
}));
|
||||
DRing::registerSignalHandlers(confHandlers);
|
||||
CPPUNIT_ASSERT(aliceAccount->addConversationMember(convId, bobUri));
|
||||
CPPUNIT_ASSERT(
|
||||
cv.wait_for(lk, std::chrono::seconds(30), [&]() { return memberMessageGenerated; }));
|
||||
// Assert that repository exists
|
||||
auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + aliceAccount->getAccountID()
|
||||
+ DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
|
||||
CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
|
||||
// Check created files
|
||||
auto bobInvited = repoPath + DIR_SEPARATOR_STR + "invited" + DIR_SEPARATOR_STR + bobUri;
|
||||
CPPUNIT_ASSERT(fileutils::isFile(bobInvited));
|
||||
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return requestReceived; }));
|
||||
memberMessageGenerated = false;
|
||||
bobAccount->acceptConversationRequest(convId);
|
||||
CPPUNIT_ASSERT(
|
||||
cv.wait_for(lk, std::chrono::seconds(30), [&]() { return memberMessageGenerated; }));
|
||||
|
||||
aliceAccount->setMessageDisplayed(convId, convId, 3);
|
||||
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(30), [&]() { return msgDisplayed; }));
|
||||
DRing::unregisterSignalHandlers();
|
||||
}
|
||||
|
||||
void
|
||||
ConversationTest::testRemoveMember()
|
||||
{
|
||||
|
Reference in New Issue
Block a user