diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index dae4296a82ede79c202988180741751ed0bf5e9c..4456e0aa748d2df1807844619a5876ae35214a2d 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -58,7 +58,10 @@ #include "llviewermessage.h" // for handle_lure #include "llviewerregion.h" #include "llimfloater.h" +#include "lltrans.h" +// callback connection to auto-call when the IM floater initializes +boost::signals2::connection gAdhocAutoCall; // static void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name) @@ -205,6 +208,39 @@ void LLAvatarActions::startCall(const LLUUID& id) make_ui_sound("UISndStartIM"); } +// static +void LLAvatarActions::startAdhocCall(const std::vector<LLUUID>& ids) +{ + if (ids.size() == 0) + { + return; + } + + // convert vector into LLDynamicArray for addSession + LLDynamicArray<LLUUID> id_array; + for (std::vector<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it) + { + id_array.push_back(*it); + } + + // create the new ad hoc voice session + const std::string title = LLTrans::getString("conference-title"); + LLUUID session_id = gIMMgr->addSession(title, IM_SESSION_CONFERENCE_START, + ids[0], id_array); + if (session_id == LLUUID::null) + { + return; + } + + // always open IM window when connecting to voice + LLIMFloater::show(session_id); + + // start the call once the floater has fully initialized + gAdhocAutoCall = LLIMModel::getInstance()->addSessionInitializedCallback(callbackAutoStartCall); + + make_ui_sound("UISndStartIM"); +} + // static bool LLAvatarActions::isCalling(const LLUUID &id) { @@ -226,7 +262,8 @@ void LLAvatarActions::startConference(const std::vector<LLUUID>& ids) { id_array.push_back(*it); } - LLUUID session_id = gIMMgr->addSession("Friends Conference", IM_SESSION_CONFERENCE_START, ids[0], id_array); + const std::string title = LLTrans::getString("conference-title"); + LLUUID session_id = gIMMgr->addSession(title, IM_SESSION_CONFERENCE_START, ids[0], id_array); if (session_id != LLUUID::null) { LLIMFloater::show(session_id); @@ -393,6 +430,17 @@ bool LLAvatarActions::callbackAddFriend(const LLSD& notification, const LLSD& re return false; } +// static +void LLAvatarActions::callbackAutoStartCall(const LLSD& data) +{ + // start the adhoc voice call now the IM panel has initialized + LLUUID session_id = data["session_id"].asUUID(); + gIMMgr->startCall(session_id); + + // and deschedule this callback as its work is done now + gAdhocAutoCall.disconnect(); +} + // static void LLAvatarActions::requestFriendship(const LLUUID& target_id, const std::string& target_name, const std::string& message) { diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h index 0ec20ae3572477764a2ffed0c9e881682b9cbb83..66ea6880dbf22267c06beeaa6665ce9491401383 100644 --- a/indra/newview/llavataractions.h +++ b/indra/newview/llavataractions.h @@ -33,6 +33,13 @@ #ifndef LL_LLAVATARACTIONS_H #define LL_LLAVATARACTIONS_H +#include "lldarray.h" +#include "llsd.h" +#include "lluuid.h" + +#include <string> +#include <vector> + /** * Friend-related actions (add, remove, offer teleport, etc) */ @@ -71,6 +78,11 @@ class LLAvatarActions */ static void startCall(const LLUUID& id); + /** + * Start an ad-hoc conference voice call with multiple users + */ + static void startAdhocCall(const std::vector<LLUUID>& ids); + /** * Start conference chat with the given avatars. */ @@ -117,6 +129,7 @@ class LLAvatarActions static bool handleRemove(const LLSD& notification, const LLSD& response); static bool handlePay(const LLSD& notification, const LLSD& response, LLUUID avatar_id); static void callback_invite_to_group(LLUUID group_id, LLUUID id); + static void callbackAutoStartCall(const LLSD& data); // Just request friendship, no dialog. static void requestFriendship(const LLUUID& target_id, const std::string& target_name, const std::string& message); diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 476d312c69b75d923ed575b9c9d48276cd84f25b..14f94d5a8883bd3e488f08e5e8a120895a1dcc76 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -862,7 +862,17 @@ bool LLIMModel::sendStartSession( return false; } - +// static +void LLIMModel::sendSessionInitialized(const LLUUID &session_id) +{ + LLIMSession* session = getInstance()->findIMSession(session_id); + if (session) + { + LLSD arg; + arg["session_id"] = session_id; + getInstance()->mSessionInitializedSignal(arg); + } +} // // Helper Functions diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index bd55bd2c30632ae9f5edb44f280698eaef7068e8..c566b111ca95cb8a061f3d37ba0f26cc7bb50c6a 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -102,6 +102,7 @@ class LLIMModel : public LLSingleton<LLIMModel> typedef boost::function<void(const LLSD&)> session_callback_t; session_signal_t mNewMsgSignal; session_signal_t mNoUnreadMsgsSignal; + session_signal_t mSessionInitializedSignal; /** * Find an IM Session corresponding to session_id @@ -116,6 +117,7 @@ class LLIMModel : public LLSingleton<LLIMModel> boost::signals2::connection addNewMsgCallback( session_callback_t cb ) { return mNewMsgSignal.connect(cb); } boost::signals2::connection addNoUnreadMsgsCallback( session_callback_t cb ) { return mNoUnreadMsgsSignal.connect(cb); } + boost::signals2::connection addSessionInitializedCallback(session_callback_t cb ) { return mSessionInitializedSignal.connect(cb); } /** * Create new session object in a model @@ -189,6 +191,7 @@ class LLIMModel : public LLSingleton<LLIMModel> static bool sendStartSession(const LLUUID& temp_session_id, const LLUUID& other_participant_id, const std::vector<LLUUID>& ids, EInstantMessage dialog); static void sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing); + static void sendSessionInitialized(const LLUUID &session_id); static void sendMessage(const std::string& utf8_text, const LLUUID& im_session_id, const LLUUID& other_participant_id, EInstantMessage dialog); diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp index 350b78ee3daf3c5a70ce5e64546d65158f0863b2..5a0c1164de9a45c28cb6d100d2bb09363648665c 100644 --- a/indra/newview/llpanelimcontrolpanel.cpp +++ b/indra/newview/llpanelimcontrolpanel.cpp @@ -92,6 +92,14 @@ void LLPanelChatControlPanel::draw() && callback_enabled; childSetEnabled("call_btn", enable_connect); + // send a signal when the floater is fully initialized + // this lets LLAvatarActions::startAdhocCall() start the call + if (enable_connect && !mInitialized) + { + LLIMModel::sendSessionInitialized(mSessionId); + mInitialized = true; + } + LLPanel::draw(); } diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h index a0d3420d231b66afd076dfd0f007acf10fd58230..923c5acbd217d53f2ba232d850510753d5af26a0 100644 --- a/indra/newview/llpanelimcontrolpanel.h +++ b/indra/newview/llpanelimcontrolpanel.h @@ -43,7 +43,9 @@ class LLParticipantList; class LLPanelChatControlPanel : public LLPanel { public: - LLPanelChatControlPanel() {}; + LLPanelChatControlPanel() : + mSessionId(LLUUID()), + mInitialized(false) {}; ~LLPanelChatControlPanel() {}; virtual BOOL postBuild(); @@ -59,6 +61,7 @@ class LLPanelChatControlPanel : public LLPanel private: LLUUID mSessionId; + bool mInitialized; }; diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index f6aded2d254ee8ff0e7d7470a187350a241c10ac..9ba94c8ca98eec7c08a3b6e5a4facdb90f27e3f4 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -755,7 +755,7 @@ void LLPanelPeople::updateButtons() buttonSetEnabled("teleport_btn", friends_tab_active && item_selected && isFriendOnline(selected_uuids.front())); buttonSetEnabled("view_profile_btn", item_selected); buttonSetEnabled("im_btn", multiple_selected); // allow starting the friends conference for multiple selection - buttonSetEnabled("call_btn", item_selected); + buttonSetEnabled("call_btn", multiple_selected); buttonSetEnabled("share_btn", item_selected && false); // not implemented yet bool none_group_selected = item_selected && selected_id.isNull(); @@ -1193,11 +1193,12 @@ void LLPanelPeople::onCallButtonClicked() if (selected_uuids.size() == 1) { // initiate a P2P voice chat with the selected user - LLAvatarActions::startCall(getCurrentItemID()); + LLAvatarActions::startCall(selected_uuids[0]); } else if (selected_uuids.size() > 1) { - // *NOTE: ad-hoc voice chat not implemented yet + // initiate an ad-hoc voice chat with multiple users + LLAvatarActions::startAdhocCall(selected_uuids); } } diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index c850dce141947d07008d4fc24c75be8d0e7fbd5b..b0a406a277c885e39f38dd5838115c6f90b2bb1c 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2863,6 +2863,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="answering-im"> Connecting... </string> + <string name="conference-title"> + Friends Conference + </string> <string name="inventory_item_offered-im"> Inventory item offered </string>