diff --git a/src/api/pluginmodel.h b/src/api/pluginmodel.h index 0cc88535f0511ab6e60350da20419d651404b62b..89a76f79ef53253575630b37b8768a428cec15e3 100644 --- a/src/api/pluginmodel.h +++ b/src/api/pluginmodel.h @@ -44,7 +44,7 @@ struct PluginDetails bool loaded = false; }; -struct MediaHandlerDetails +struct PluginHandlerDetails { QString id = ""; QString name = ""; @@ -76,13 +76,13 @@ public: * Get list of installed plugins * @return plugins installed */ - VectorString listAvailablePlugins() const; + VectorString getInstalledPlugins() const; /** * Get list of loaded plugins * @return plugins loaded */ - VectorString listLoadedPlugins() const; + VectorString getLoadedPlugins() const; /** * Get details of installed plugin @@ -118,7 +118,7 @@ public: * List all plugins Media Handlers * @return List of all plugins Media Handlers */ - VectorString listCallMediaHandlers() const; + VectorString getCallMediaHandlers() const; /** * Toggle media handler @@ -127,17 +127,31 @@ public: const QString& callId, bool toggle); + VectorString getChatHandlers() const; + + /** + * Toggle chat handler + */ + Q_INVOKABLE void toggleChatHandler(const QString& chatHandlerId, + const QString& accountId, + const QString& peerId, + bool toggle); + /** * Verify if there is an active plugin media handler * @return Map with name and status */ - MapStringVectorString getCallMediaHandlerStatus(const QString& callId); + VectorString getCallMediaHandlerStatus(const QString& callId); /** * Get details of installed plugins media handlers * @return Media Handler Details */ - plugin::MediaHandlerDetails getCallMediaHandlerDetails(const QString& mediaHandlerId); + plugin::PluginHandlerDetails getCallMediaHandlerDetails(const QString& mediaHandlerId); + + VectorString getChatHandlerStatus(const QString& accountId, const QString& peerId); + + plugin::PluginHandlerDetails getChatHandlerDetails(const QString& chatHandlerId); /** * Get preferences map of installed plugin @@ -164,7 +178,11 @@ public: * @return true if preference was succesfully reset */ Q_INVOKABLE bool resetPluginPreferencesValues(const QString& path); + +Q_SIGNALS: + void chatHandlerStatusUpdated(bool isVisible); }; } // namespace api } // namespace lrc +Q_DECLARE_METATYPE(lrc::api::PluginModel*) diff --git a/src/chatview.cpp b/src/chatview.cpp index e1a4cfc780129a5acac3a54f732b8c848ae6fbb1..ff7ac388b2c36610b12b727cfc63e73a446921e3 100644 --- a/src/chatview.cpp +++ b/src/chatview.cpp @@ -29,6 +29,7 @@ getTranslatedStrings(bool qwebview) return { {"Hide chat view", QObject::tr("Hide chat view")}, {"Place video call", QObject::tr("Place video call")}, + {"Show available plugins", QObject::tr("Show available plugins")}, {"Place audio call", QObject::tr("Place audio call")}, {"Add to conversations", QObject::tr("Add to conversations")}, {"Unban contact", QObject::tr("Unban contact")}, diff --git a/src/pluginmodel.cpp b/src/pluginmodel.cpp index 5de052e25853f89679634a5e4ff3940578d6aa3d..1bc38e9acb731032699da3f8b568b4b90f56682f 100644 --- a/src/pluginmodel.cpp +++ b/src/pluginmodel.cpp @@ -52,6 +52,10 @@ void PluginModel::setPluginsEnabled(bool enable) { PluginManager::instance().setPluginsEnabled(enable); + if (!enable) + emit chatHandlerStatusUpdated(false); + else + emit chatHandlerStatusUpdated(getChatHandlers().size() > 0); } bool @@ -61,15 +65,15 @@ PluginModel::getPluginsEnabled() const } VectorString -PluginModel::listAvailablePlugins() const +PluginModel::getInstalledPlugins() const { - return VectorString::fromList(PluginManager::instance().listAvailablePlugins()); + return VectorString::fromList(PluginManager::instance().getInstalledPlugins()); } VectorString -PluginModel::listLoadedPlugins() const +PluginModel::getLoadedPlugins() const { - return VectorString::fromList(PluginManager::instance().listLoadedPlugins()); + return VectorString::fromList(PluginManager::instance().getLoadedPlugins()); } plugin::PluginDetails @@ -86,7 +90,7 @@ PluginModel::getPluginDetails(const QString& path) result.iconPath = details["iconPath"]; } - VectorString loadedPlugins = listLoadedPlugins(); + VectorString loadedPlugins = getLoadedPlugins(); if (std::find(loadedPlugins.begin(), loadedPlugins.end(), result.path) != loadedPlugins.end()) { result.loaded = true; } @@ -113,19 +117,24 @@ bool PluginModel::loadPlugin(const QString& path) { bool status = PluginManager::instance().loadPlugin(path); + if (getChatHandlers().size() > 0) + emit chatHandlerStatusUpdated(getPluginsEnabled()); return status; } bool PluginModel::unloadPlugin(const QString& path) { - return PluginManager::instance().unloadPlugin(path); + bool status = PluginManager::instance().unloadPlugin(path); + if (getChatHandlers().size() <= 0) + emit chatHandlerStatusUpdated(false); + return status; } VectorString -PluginModel::listCallMediaHandlers() const +PluginModel::getCallMediaHandlers() const { - return VectorString::fromList(PluginManager::instance().listCallMediaHandlers()); + return VectorString::fromList(PluginManager::instance().getCallMediaHandlers()); } void @@ -136,21 +145,36 @@ PluginModel::toggleCallMediaHandler(const QString& mediaHandlerId, PluginManager::instance().toggleCallMediaHandler(mediaHandlerId, callId, toggle); } -MapStringVectorString +VectorString +PluginModel::getChatHandlers() const +{ + return VectorString::fromList(PluginManager::instance().getChatHandlers()); +} + +void +PluginModel::toggleChatHandler(const QString& chatHandlerId, + const QString& accountId, + const QString& peerId, + bool toggle) +{ + PluginManager::instance().toggleChatHandler(chatHandlerId, accountId, peerId, toggle); +} + +VectorString PluginModel::getCallMediaHandlerStatus(const QString& callId) { - return PluginManager::instance().getCallMediaHandlerStatus(callId); + return VectorString::fromList(PluginManager::instance().getCallMediaHandlerStatus(callId)); } -plugin::MediaHandlerDetails +plugin::PluginHandlerDetails PluginModel::getCallMediaHandlerDetails(const QString& mediaHandlerId) { if (mediaHandlerId.isEmpty()) { - return plugin::MediaHandlerDetails(); + return plugin::PluginHandlerDetails(); } MapStringString mediaHandlerDetails = PluginManager::instance().getCallMediaHandlerDetails( mediaHandlerId); - plugin::MediaHandlerDetails result; + plugin::PluginHandlerDetails result; if (!mediaHandlerDetails.empty()) { result.id = mediaHandlerId; result.iconPath = mediaHandlerDetails["iconPath"]; @@ -161,6 +185,31 @@ PluginModel::getCallMediaHandlerDetails(const QString& mediaHandlerId) return result; } +VectorString +PluginModel::getChatHandlerStatus(const QString& accountId, const QString& peerId) +{ + return VectorString::fromList(PluginManager::instance().getChatHandlerStatus(accountId, peerId)); +} + +plugin::PluginHandlerDetails +PluginModel::getChatHandlerDetails(const QString& chatHandlerId) +{ + if (chatHandlerId.isEmpty()) { + return plugin::PluginHandlerDetails(); + } + MapStringString chatHandlerDetails = PluginManager::instance().getChatHandlerDetails( + chatHandlerId); + plugin::PluginHandlerDetails result; + if (!chatHandlerDetails.empty()) { + result.id = chatHandlerId; + result.iconPath = chatHandlerDetails["iconPath"]; + result.name = chatHandlerDetails["name"]; + result.pluginId = chatHandlerDetails["pluginId"]; + } + + return result; +} + VectorMapStringString PluginModel::getPluginPreferences(const QString& path) { diff --git a/src/qtwrapper/pluginmanager.cpp b/src/qtwrapper/pluginmanager.cpp index 668740c4ff7502a3de9258aeeee24b163bc134fb..ba9f8f94971cc89df02a60c80e190add77f9f611 100644 --- a/src/qtwrapper/pluginmanager.cpp +++ b/src/qtwrapper/pluginmanager.cpp @@ -38,15 +38,15 @@ PluginManagerInterface::getPluginDetails(const QString& path) } QStringList -PluginManagerInterface::listAvailablePlugins() +PluginManagerInterface::getInstalledPlugins() { - return convertStringList(DRing::listAvailablePlugins()); + return convertStringList(DRing::getInstalledPlugins()); } QStringList -PluginManagerInterface::listLoadedPlugins() +PluginManagerInterface::getLoadedPlugins() { - return convertStringList(DRing::listLoadedPlugins()); + return convertStringList(DRing::getLoadedPlugins()); } int @@ -62,9 +62,9 @@ PluginManagerInterface::uninstallPlugin(const QString& pluginRootPath) } QStringList -PluginManagerInterface::listCallMediaHandlers() +PluginManagerInterface::getCallMediaHandlers() { - return convertStringList(DRing::listCallMediaHandlers()); + return convertStringList(DRing::getCallMediaHandlers()); } void @@ -75,10 +75,28 @@ PluginManagerInterface::toggleCallMediaHandler(const QString& mediaHandlerId, DRing::toggleCallMediaHandler(mediaHandlerId.toStdString(), callId.toStdString(), toggle); } -MapStringVectorString +QStringList +PluginManagerInterface::getChatHandlers() +{ + return convertStringList(DRing::getChatHandlers()); +} + +void +PluginManagerInterface::toggleChatHandler(const QString& chatHandlerId, + const QString& accountId, + const QString& peerId, + bool toggle) +{ + DRing::toggleChatHandler(chatHandlerId.toStdString(), + accountId.toStdString(), + peerId.toStdString(), + toggle); +} + +QStringList PluginManagerInterface::getCallMediaHandlerStatus(const QString& callId) { - return convertMap(DRing::getCallMediaHandlerStatus(callId.toStdString())); + return convertStringList(DRing::getCallMediaHandlerStatus(callId.toStdString())); } MapStringString @@ -87,6 +105,19 @@ PluginManagerInterface::getCallMediaHandlerDetails(const QString& mediaHandlerId return convertMap(DRing::getCallMediaHandlerDetails(mediaHandlerId.toStdString())); } +QStringList +PluginManagerInterface::getChatHandlerStatus(const QString& accountId, const QString& peerId) +{ + return convertStringList( + DRing::getChatHandlerStatus(accountId.toStdString(), peerId.toStdString())); +} + +MapStringString +PluginManagerInterface::getChatHandlerDetails(const QString& chatHandlerId) +{ + return convertMap(DRing::getChatHandlerDetails(chatHandlerId.toStdString())); +} + void PluginManagerInterface::setPluginsEnabled(bool enable) { diff --git a/src/qtwrapper/pluginmanagerMock.cpp b/src/qtwrapper/pluginmanagerMock.cpp index 7363c0af235ef55841577a6aa235aec55ffa526b..6a2277d6ae8288c4a0d85ee1a19b4f77e4dd2623 100644 --- a/src/qtwrapper/pluginmanagerMock.cpp +++ b/src/qtwrapper/pluginmanagerMock.cpp @@ -38,13 +38,13 @@ PluginManagerInterface::getPluginDetails(const QString& path) } QStringList -PluginManagerInterface::listAvailablePlugins() +PluginManagerInterface::getInstalledPlugins() { return {}; } QStringList -PluginManagerInterface::listLoadedPlugins() +PluginManagerInterface::getLoadedPlugins() { return {}; } @@ -62,7 +62,7 @@ PluginManagerInterface::uninstallPlugin(const QString& pluginRootPath) } QStringList -PluginManagerInterface::listCallMediaHandlers() +PluginManagerInterface::getCallMediaHandlers() { return {}; } @@ -73,7 +73,20 @@ PluginManagerInterface::toggleCallMediaHandler(const QString& mediaHandlerId, bool toggle) {} -MapStringVectorString +QStringList +PluginManagerInterface::getChatHandlers() +{ + return {}; +} + +void +PluginManagerInterface::toggleChatHandler(const QString& chatHandlerId, + const QString& accountId, + const QString& peerId, + bool toggle) +{} + +QStringList PluginManagerInterface::getCallMediaHandlerStatus(const QString& callId) { return {}; @@ -85,6 +98,18 @@ PluginManagerInterface::getCallMediaHandlerDetails(const QString& mediaHandlerId return {}; } +QStringList +PluginManagerInterface::getChatHandlerStatus(const QString& accountId, const QString& peerId) +{ + return {}; +} + +MapStringString +PluginManagerInterface::getChatHandlerDetails(const QString& chatHandlerId) +{ + return {}; +} + void PluginManagerInterface::setPluginsEnabled(bool enable) {} diff --git a/src/qtwrapper/pluginmanager_wrap.h b/src/qtwrapper/pluginmanager_wrap.h index e85fb9fc5c588bc9aac7f268d39cf3484c2f7dcc..244cbc1ce4b22c964966a2d22f6e9757fb661b5d 100644 --- a/src/qtwrapper/pluginmanager_wrap.h +++ b/src/qtwrapper/pluginmanager_wrap.h @@ -50,22 +50,33 @@ public Q_SLOTS: // METHODS MapStringString getPluginDetails(const QString& path); - QStringList listAvailablePlugins(); + QStringList getInstalledPlugins(); - QStringList listLoadedPlugins(); + QStringList getLoadedPlugins(); int installPlugin(const QString& jplPath, bool force); int uninstallPlugin(const QString& pluginRootPath); - QStringList listCallMediaHandlers(); + QStringList getCallMediaHandlers(); void toggleCallMediaHandler(const QString& mediaHandlerId, const QString& callId, bool toggle); - MapStringVectorString getCallMediaHandlerStatus(const QString& callId); + QStringList getChatHandlers(); + + void toggleChatHandler(const QString& chatHandlerId, + const QString& accountId, + const QString& peerId, + bool toggle); + + QStringList getCallMediaHandlerStatus(const QString& callId); MapStringString getCallMediaHandlerDetails(const QString& mediaHandlerId); + QStringList getChatHandlerStatus(const QString& accountId, const QString& peerId); + + MapStringString getChatHandlerDetails(const QString& chatHandlerId); + void setPluginsEnabled(bool enable); bool getPluginsEnabled(); diff --git a/src/web-chatview/chatview.html b/src/web-chatview/chatview.html index 1bd4d90549b628e760355934bb19741c90d944b7..e2df4facdc2ba3571296438054018306a418c66c 100644 --- a/src/web-chatview/chatview.html +++ b/src/web-chatview/chatview.html @@ -43,6 +43,12 @@ </svg> </div> </div> + <div id="pluginsButton" style="display:none" class="nav-button action-button nav-right" onclick="openPluginHandlersList()"> + <svg class="svgicon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> + <path d="M0 0h24v24H0V0z" fill="none" /> + <path d="M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7s2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11z"/> + </svg> + </div> <div id="addToConversationsButton" class="nav-button action-button nav-right" onclick="addToConversations()"> <svg class="svgicon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> <path d="M0 0h24v24H0z" fill="none" /> @@ -90,7 +96,8 @@ <div id="typing_indicator_container"></div> <div id="back_to_bottom_button_container"> - <div id="back_to_bottom_button" onclick="back_to_bottom()">Jump to latest ▼</div> + <div id="back_to_bottom_button" onclick="back_to_bottom()">Jump to latest ▼ +</div> </div> <div id="send_inteface_container" onresize="updateBackToBottomContainer()"> <div id="sendMessage"> diff --git a/src/web-chatview/chatview.js b/src/web-chatview/chatview.js index d13ee9bd7d574eadb45c715d066c1878d8149ef4..3df38f6a3865680cc8e592c55644f2127613c3a4 100644 --- a/src/web-chatview/chatview.js +++ b/src/web-chatview/chatview.js @@ -34,6 +34,7 @@ const addToConversationsButton = document.getElementById("addToConversationsButt const placeAudioCallButton = document.getElementById("placeAudioCallButton") const backButton = document.getElementById("backButton") const placeCallButton = document.getElementById("placeCallButton") +const pluginsButton = document.getElementById("pluginsButton") const unbanButton = document.getElementById("unbanButton") const acceptButton = document.getElementById("acceptButton") const refuseButton = document.getElementById("refuseButton") @@ -165,6 +166,7 @@ function set_titles() { if (use_qt){ backButton.title = i18nStringData["Hide chat view"] placeCallButton.title = i18nStringData["Place video call"] + pluginsButton.title = i18nStringData["Show available plugins"] placeAudioCallButton.title = i18nStringData["Place audio call"] addToConversationsButton.title = i18nStringData["Add to conversations"] unbanButton.title = i18nStringData["Unban contact"] @@ -180,6 +182,7 @@ function set_titles() { } else { backButton.title = i18n.gettext("Hide chat view") placeCallButton.title = i18n.gettext("Place video call") + pluginsButton.title = i18n.gettext("Show available plugins") placeAudioCallButton.title = i18n.gettext("Place audio call") addToConversationsButton.title = i18n.gettext("Add to conversations") unbanButton.title = i18n.gettext("Unban contact") @@ -412,6 +415,21 @@ function displayRecordControls(isVisible) { } } +/** + * Hide or show plugin controls, and update body top padding accordingly. + * + * @param isVisible whether navbar should be displayed or not + */ +/* exported displayPluginControl */ +function displayPluginControl(isVisible) { + if (isVisible) { + pluginsButton.style.removeProperty("display") + } else { + pluginsButton.style.setProperty("display", "none") + } +} + + /** * Hide or show message bar, and update body bottom padding accordingly. * @@ -579,6 +597,13 @@ function backToWelcomeView() { window.prompt("CLOSE_CHATVIEW") } +function openPluginHandlersList() { + var rect = pluginsButton.getBoundingClientRect() + if (!use_qt) { + window.prompt(`LIST_PLUGIN_HANDLERS:${rect.left + rect.width / 2}x${rect.bottom}`) + } +} + /** * Transform a date to a string group like "1 hour ago". *