diff options
Diffstat (limited to 'indra/newview/llpanelpeople.cpp')
-rw-r--r-- | indra/newview/llpanelpeople.cpp | 496 |
1 files changed, 484 insertions, 12 deletions
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 4138558bad..03135ce580 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -28,6 +28,8 @@ // libs #include "llavatarname.h" +#include "llconversationview.h" +#include "llfloaterimcontainer.h" #include "llfloaterreg.h" #include "llfloatersidepanelcontainer.h" #include "llmenubutton.h" @@ -48,7 +50,10 @@ #include "llavataractions.h" #include "llavatarlist.h" #include "llavatarlistitem.h" +#include "llavatarnamecache.h" #include "llcallingcard.h" // for LLAvatarTracker +#include "llcallbacklist.h" +#include "llerror.h" #include "llfloateravatarpicker.h" //#include "llfloaterminiinspector.h" #include "llfriendcard.h" @@ -57,25 +62,65 @@ #include "llinventoryobserver.h" #include "llnetmap.h" #include "llpanelpeoplemenus.h" +#include "llparticipantlist.h" +#include "llpersonfolderview.h" +#include "llpersonmodelcommon.h" +#include "llpersontabview.h" #include "llsidetraypanelcontainer.h" #include "llrecentpeople.h" #include "llviewercontrol.h" // for gSavedSettings #include "llviewermenu.h" // for gMenuHolder #include "llvoiceclient.h" #include "llworld.h" +#include "llsociallist.h" #include "llspeakers.h" +#include "llfloaterwebcontent.h" +#include "llurlaction.h" +#include "llcommandhandler.h" #define FRIEND_LIST_UPDATE_TIMEOUT 0.5 #define NEARBY_LIST_UPDATE_INTERVAL 1 +#define FBCTEST_LIST_UPDATE_INTERVAL 0.25 static const std::string NEARBY_TAB_NAME = "nearby_panel"; static const std::string FRIENDS_TAB_NAME = "friends_panel"; static const std::string GROUP_TAB_NAME = "groups_panel"; static const std::string RECENT_TAB_NAME = "recent_panel"; static const std::string BLOCKED_TAB_NAME = "blocked_panel"; // blocked avatars - +static const std::string FBCTEST_TAB_NAME = "fbctest_panel"; +static const std::string FBCTESTTWO_TAB_NAME = "fbctesttwo_panel"; static const std::string COLLAPSED_BY_USER = "collapsed_by_user"; +class LLFacebookConnectHandler : public LLCommandHandler +{ +public: + LLFacebookConnectHandler() : LLCommandHandler("fbc", UNTRUSTED_THROTTLE), mPanelPeople(NULL) { } + + LLPanelPeople* mPanelPeople; + + bool handle(const LLSD& tokens, const LLSD& query_map, + LLMediaCtrl* web) + { + if (tokens.size() > 0) + { + if (tokens[0].asString() == "connect") + { + if (query_map.has("code")) + { + if (mPanelPeople) + { + mPanelPeople->connectToFacebook(query_map["code"]); + mPanelPeople = NULL; + } + } + return true; + } + } + return false; + } +}; +LLFacebookConnectHandler gFacebookConnectHandler; + /** Comparator for comparing avatar items by last interaction date */ class LLAvatarItemRecentComparator : public LLAvatarItemComparator { @@ -489,10 +534,52 @@ public: } }; +/** + * Periodically updates the FBC test list after a login is initiated. + * + * The period is defined by FBCTEST_LIST_UPDATE_INTERVAL constant. + */ +class LLFbcTestListUpdater : public LLAvatarListUpdater +{ + LOG_CLASS(LLFbcTestListUpdater); + +public: + LLFbcTestListUpdater(callback_t cb) + : LLAvatarListUpdater(cb, FBCTEST_LIST_UPDATE_INTERVAL) + { + setActive(false); + } + + /*virtual*/ void setActive(bool val) + { + if (val) + { + // update immediately and start regular updates + update(); + mEventTimer.start(); + } + else + { + // stop regular updates + mEventTimer.stop(); + } + } + + /*virtual*/ BOOL tick() + { + update(); + return FALSE; + } +private: +}; + //============================================================================= LLPanelPeople::LLPanelPeople() : LLPanel(), + mConnectedToFbc(false), + mPersonFolderView(NULL), + mTryToConnectToFbc(true), mTabContainer(NULL), mOnlineFriendList(NULL), mAllFriendList(NULL), @@ -504,8 +591,15 @@ LLPanelPeople::LLPanelPeople() mFriendListUpdater = new LLFriendListUpdater(boost::bind(&LLPanelPeople::updateFriendList, this)); mNearbyListUpdater = new LLNearbyListUpdater(boost::bind(&LLPanelPeople::updateNearbyList, this)); mRecentListUpdater = new LLRecentListUpdater(boost::bind(&LLPanelPeople::updateRecentList, this)); + mFbcTestListUpdater = new LLFbcTestListUpdater(boost::bind(&LLPanelPeople::updateFbcTestList, this)); mButtonsUpdater = new LLButtonsUpdater(boost::bind(&LLPanelPeople::updateButtons, this)); + mCommitCallbackRegistrar.add("People.loginFBC", boost::bind(&LLPanelPeople::onLoginFbcButtonClicked, this)); + mCommitCallbackRegistrar.add("People.requestFBC", boost::bind(&LLPanelPeople::onFacebookAppRequestClicked, this)); + mCommitCallbackRegistrar.add("People.sendFBC", boost::bind(&LLPanelPeople::onFacebookAppSendClicked, this)); + mCommitCallbackRegistrar.add("People.testaddFBC", boost::bind(&LLPanelPeople::onFacebookTestAddClicked, this)); + mCommitCallbackRegistrar.add("People.testaddFBCFolderView", boost::bind(&LLPanelPeople::addTestParticipant, this)); + mCommitCallbackRegistrar.add("People.AddFriend", boost::bind(&LLPanelPeople::onAddFriendButtonClicked, this)); mCommitCallbackRegistrar.add("People.AddFriendWizard", boost::bind(&LLPanelPeople::onAddFriendWizButtonClicked, this)); mCommitCallbackRegistrar.add("People.DelFriend", boost::bind(&LLPanelPeople::onDeleteFriendButtonClicked, this)); @@ -532,11 +626,14 @@ LLPanelPeople::~LLPanelPeople() delete mNearbyListUpdater; delete mFriendListUpdater; delete mRecentListUpdater; + delete mFbcTestListUpdater; if(LLVoiceClient::instanceExists()) { LLVoiceClient::getInstance()->removeObserver(this); } + + if (mFbcTestBrowserHandle.get()) mFbcTestBrowserHandle.get()->die(); } void LLPanelPeople::onFriendsAccordionExpandedCollapsed(LLUICtrl* ctrl, const LLSD& param, LLAvatarList* avatar_list) @@ -571,6 +668,7 @@ BOOL LLPanelPeople::postBuild() getChild<LLFilterEditor>("friends_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2)); getChild<LLFilterEditor>("groups_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2)); getChild<LLFilterEditor>("recent_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2)); + getChild<LLFilterEditor>("fbc_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2)); mTabContainer = getChild<LLTabContainer>("tabs"); mTabContainer->setCommitCallback(boost::bind(&LLPanelPeople::onTabSelected, this, _2)); @@ -616,6 +714,74 @@ BOOL LLPanelPeople::postBuild() mAllFriendList->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu); mOnlineFriendList->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu); + LLPanel * social_tab = getChild<LLPanel>(FBCTEST_TAB_NAME); + mFacebookFriends = social_tab->getChild<LLSocialList>("facebook_friends"); + social_tab->setVisibleCallback(boost::bind(&Updater::setActive, mFbcTestListUpdater, _2)); + + //===Test START======================================================================== + + LLPanel * socialtwo_tab = getChild<LLPanel>(FBCTESTTWO_TAB_NAME); + + //Create folder view + LLPersonModelCommon* base_item = new LLPersonModelCommon(mPersonFolderViewModel); + + LLPersonFolderView::Params folder_view_params(LLUICtrlFactory::getDefaultParams<LLPersonFolderView>()); + + folder_view_params.parent_panel = socialtwo_tab; + folder_view_params.listener = base_item; + folder_view_params.view_model = &mPersonFolderViewModel; + folder_view_params.root = NULL; + folder_view_params.use_ellipses = false; + folder_view_params.options_menu = "menu_conversation.xml"; + folder_view_params.name = "fbcfolderview"; + mPersonFolderView = LLUICtrlFactory::create<LLPersonFolderView>(folder_view_params); + + //Create scroller + LLRect scroller_view_rect = socialtwo_tab->getRect(); + scroller_view_rect.mTop -= 2+27; // 27 is the height of the top toolbar + scroller_view_rect.mRight -= 4; + scroller_view_rect.mLeft += 2; + LLScrollContainer::Params scroller_params(LLUICtrlFactory::getDefaultParams<LLFolderViewScrollContainer>()); + scroller_params.rect(scroller_view_rect); + + LLScrollContainer* scroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params); + socialtwo_tab->addChildInBack(scroller); + scroller->addChild(mPersonFolderView); + scroller->setFollowsAll(); + mPersonFolderView->setScrollContainer(scroller); + mPersonFolderView->setFollowsAll(); + + //Create a person tab + LLPersonTabModel* item = new LLPersonTabModel("Facebook Friends", mPersonFolderViewModel); + LLPersonTabView::Params params; + params.name = item->getDisplayName(); + params.root = mPersonFolderView; + params.listener = item; + params.tool_tip = params.name; + LLPersonTabView * widget = LLUICtrlFactory::create<LLPersonTabView>(params); + widget->addToFolder(mPersonFolderView); + + mPersonFolderView->mPersonFolderModelMap[item->getID()] = item; + mPersonFolderView->mPersonFolderViewMap[item->getID()] = widget; + + //Create a person tab + item = new LLPersonTabModel("Facebook Friends Tab Two", mPersonFolderViewModel); + params.name = item->getDisplayName(); + params.root = mPersonFolderView; + params.listener = item; + params.tool_tip = params.name; + widget = LLUICtrlFactory::create<LLPersonTabView>(params); + widget->addToFolder(mPersonFolderView); + + mPersonFolderView->mPersonFolderModelMap[item->getID()] = item; + mPersonFolderView->mPersonFolderViewMap[item->getID()] = widget; + + gIdleCallbacks.addFunction(idle, this); + + //===Test END======================================================================== + + + setSortOrder(mRecentList, (ESortOrder)gSavedSettings.getU32("RecentPeopleSortOrder"), false); setSortOrder(mAllFriendList, (ESortOrder)gSavedSettings.getU32("FriendsSortOrder"), false); setSortOrder(mNearbyList, (ESortOrder)gSavedSettings.getU32("NearbyPeopleSortOrder"), false); @@ -664,6 +830,15 @@ BOOL LLPanelPeople::postBuild() // Must go after setting commit callback and initializing all pointers to children. mTabContainer->selectTabByName(NEARBY_TAB_NAME); + mFBCGearButton = getChild<LLMenuButton>("fbc_options_btn"); + + LLToggleableMenu* fbc_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_gear_fbc.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + if(fbc_menu) + { + mFBCMenuHandle = fbc_menu->getHandle(); + mFBCGearButton->setMenu(fbc_menu); + } + LLVoiceClient::getInstance()->addObserver(this); // call this method in case some list is empty and buttons can be in inconsistent state @@ -686,6 +861,12 @@ void LLPanelPeople::onChange(EStatusType status, const std::string &channelURI, updateButtons(); } +void LLPanelPeople::idle(void * user_data) +{ + LLPanelPeople * self = static_cast<LLPanelPeople *>(user_data); + self->mPersonFolderView->update(); +} + void LLPanelPeople::updateFriendListHelpText() { // show special help text for just created account to help finding friends. EXT-4836 @@ -786,6 +967,21 @@ void LLPanelPeople::updateRecentList() mRecentList->setDirty(); } +void LLPanelPeople::updateFbcTestList() +{ + if (mTryToConnectToFbc) + { + // try to reconnect to facebook! + tryToReconnectToFacebook(); + + // don't try again + mTryToConnectToFbc = false; + + // stop updating + mFbcTestListUpdater->setActive(false); + } +} + void LLPanelPeople::updateButtons() { std::string cur_tab = getActiveTabName(); @@ -870,6 +1066,13 @@ LLUUID LLPanelPeople::getCurrentItemID() const if (cur_tab == BLOCKED_TAB_NAME) return LLUUID::null; // FIXME? + + if (cur_tab == FBCTEST_TAB_NAME) + return LLUUID::null; + + if (cur_tab == FBCTESTTWO_TAB_NAME) + return LLUUID::null; + llassert(0 && "unknown tab selected"); return LLUUID::null; @@ -893,6 +1096,10 @@ void LLPanelPeople::getCurrentItemIDs(uuid_vec_t& selected_uuids) const mGroupList->getSelectedUUIDs(selected_uuids); else if (cur_tab == BLOCKED_TAB_NAME) selected_uuids.clear(); // FIXME? + else if (cur_tab == FBCTEST_TAB_NAME) + return; + else if (cur_tab == FBCTESTTWO_TAB_NAME) + return; else llassert(0 && "unknown tab selected"); @@ -989,23 +1196,23 @@ void LLPanelPeople::onFilterEdit(const std::string& search_string) { // store accordion tabs opened/closed state before any manipulation with accordion tabs if (!saved_filter.empty()) - { - notifyChildren(LLSD().with("action","store_state")); - } + { + notifyChildren(LLSD().with("action","store_state")); + } mOnlineFriendList->setNameFilter(filter); mAllFriendList->setNameFilter(filter); - setAccordionCollapsedByUser("tab_online", false); - setAccordionCollapsedByUser("tab_all", false); - showFriendsAccordionsIfNeeded(); + setAccordionCollapsedByUser("tab_online", false); + setAccordionCollapsedByUser("tab_all", false); + showFriendsAccordionsIfNeeded(); // restore accordion tabs state _after_ all manipulations if(saved_filter.empty()) - { - notifyChildren(LLSD().with("action","restore_state")); - } -} + { + notifyChildren(LLSD().with("action","restore_state")); + } + } else if (cur_tab == GROUP_TAB_NAME) { mGroupList->setNameFilter(filter); @@ -1014,6 +1221,10 @@ void LLPanelPeople::onFilterEdit(const std::string& search_string) { mRecentList->setNameFilter(filter); } + else if (cur_tab == FBCTESTTWO_TAB_NAME) + { + mPersonFolderViewModel.getFilter().setFilterSubString(filter); + } } void LLPanelPeople::onTabSelected(const LLSD& param) @@ -1225,7 +1436,7 @@ void LLPanelPeople::onFriendsViewSortMenuItemClicked(const LLSD& userdata) mAllFriendList->showPermissions(show_permissions); mOnlineFriendList->showPermissions(show_permissions); } -} + } void LLPanelPeople::onGroupsViewSortMenuItemClicked(const LLSD& userdata) { @@ -1446,4 +1657,265 @@ bool LLPanelPeople::isAccordionCollapsedByUser(const std::string& name) return isAccordionCollapsedByUser(getChild<LLUICtrl>(name)); } +void LLPanelPeople::openFacebookWeb(std::string url) +{ + gFacebookConnectHandler.mPanelPeople = this; + LLUrlAction::openURLExternal(url); +} + +void LLPanelPeople::showFacebookFriends(const LLSD& friends) +{ + mFacebookFriends->clear(); + + for (LLSD::map_const_iterator i = friends.beginMap(); i != friends.endMap(); ++i) + { + std::string name = i->second["name"].asString(); + LLUUID agent_id = i->second.has("agent_id") ? i->second["agent_id"].asUUID() : LLUUID(NULL); + + //add to avatar list + mFacebookFriends->addNewItem(agent_id, name, false); + + //Add to folder view + LLPersonTabModel * session_model = dynamic_cast<LLPersonTabModel *>(mPersonFolderView->mPersonFolderModelMap.begin()->second); + if(session_model) + { + addParticipantToModel(session_model, agent_id, name); + } + } +} + +void LLPanelPeople::addTestParticipant() +{ + std::string suffix("Aa"); + std::string prefix("Test Name"); + for(int i = 0; i < 300; ++i) + { + LLPersonTabModel * person_folder_model = dynamic_cast<LLPersonTabModel *>(mPersonFolderView->mPersonFolderModelMap.begin()->second); + std::string name = prefix + " " + suffix; + addParticipantToModel(person_folder_model, gAgent.getID(), name); + // Next suffix : Aa, Ab, Ac ... Az, Ba, Bb, Bc ... Bz, Ca, Cb ... + suffix[1]+=1; + if (suffix[1]=='{') + { + suffix[1]='a'; + suffix[0]+=1; + if (suffix[0]=='[') + suffix[0]='A'; + } + } +} + +void LLPanelPeople::addParticipantToModel(LLPersonTabModel * person_folder_model, const LLUUID& agent_id, const std::string& name) +{ + LLPersonModel* person_model = NULL; + + LLAvatarName avatar_name; + bool avatar_name_exists = LLAvatarNameCache::get(agent_id, &avatar_name); + + std::string aggregated_name = avatar_name_exists ? name + " (" + avatar_name.getDisplayName() + ") " : name; + + person_model = new LLPersonModel(agent_id, aggregated_name, mPersonFolderViewModel); + person_folder_model->addParticipant(person_model); +} + +void LLPanelPeople::hideFacebookFriends() +{ + mFacebookFriends->clear(); +} + +class FacebookConnectResponder : public LLHTTPClient::Responder +{ +public: + + LLPanelPeople * mPanelPeople; + + FacebookConnectResponder(LLPanelPeople * panel_people) : mPanelPeople(panel_people) {} + + /*virtual*/ void completed(U32 status, const std::string& reason, const LLSD& content) + { + if (isGoodStatus(status)) + { + llinfos << content << llendl; + + // grab some graph data now that we are connected + mPanelPeople->mConnectedToFbc = true; + mPanelPeople->loadFacebookFriends(); + } + else + { + llinfos << "failed to get response. reason: " << reason << " status: " << status << llendl; + } + } + + /*virtual*/ void completedHeader(U32 status, const std::string& reason, const LLSD& content) + { + if (status == 302) + { + mPanelPeople->openFacebookWeb(content["location"]); + } + } +}; + +class FacebookDisconnectResponder : public LLHTTPClient::Responder +{ +public: + + LLPanelPeople * mPanelPeople; + + FacebookDisconnectResponder(LLPanelPeople * panel_people) : mPanelPeople(panel_people) {} + + /*virtual*/ void completed(U32 status, const std::string& reason, const LLSD& content) + { + if (isGoodStatus(status)) + { + llinfos << content << llendl; + + // hide all the facebook stuff + mPanelPeople->mConnectedToFbc = false; + mPanelPeople->hideFacebookFriends(); + } + else + { + llinfos << "failed to get response. reason: " << reason << " status: " << status << llendl; + } + } +}; + +class FacebookConnectedResponder : public LLHTTPClient::Responder +{ +public: + + LLPanelPeople * mPanelPeople; + bool mShowLoginIfNotConnected; + + FacebookConnectedResponder(LLPanelPeople * panel_people, bool show_login_if_not_connected) : mPanelPeople(panel_people), mShowLoginIfNotConnected(show_login_if_not_connected) {} + + /*virtual*/ void completed(U32 status, const std::string& reason, const LLSD& content) + { + if (isGoodStatus(status)) + { + llinfos << content << llendl; + + // grab some graph data if already connected + mPanelPeople->mConnectedToFbc = true; + mPanelPeople->loadFacebookFriends(); + } + else + { + llinfos << "failed to get response. reason: " << reason << " status: " << status << llendl; + + // show the facebook login page if not connected yet + if (status == 404 && mShowLoginIfNotConnected) + { + mPanelPeople->connectToFacebook(); + } + } + } +}; + +class FacebookFriendsResponder : public LLHTTPClient::Responder +{ +public: + + LLPanelPeople * mPanelPeople; + + FacebookFriendsResponder(LLPanelPeople * panel_people) : mPanelPeople(panel_people) {} + + /*virtual*/ void completed(U32 status, const std::string& reason, const LLSD& content) + { + if (isGoodStatus(status)) + { + llinfos << content << llendl; + + // display the list of friends + mPanelPeople->showFacebookFriends(content); + } + else + { + llinfos << "failed to get response. reason: " << reason << " status: " << status << llendl; + } + } + + /*virtual*/ void completedHeader(U32 status, const std::string& reason, const LLSD& content) + { + if (status == 302) + { + mPanelPeople->openFacebookWeb(content["location"]); + } + } +}; + +void LLPanelPeople::loadFacebookFriends() +{ + LLHTTPClient::get(getFacebookConnectURL("/friend"), new FacebookFriendsResponder(this)); +} + +void LLPanelPeople::tryToReconnectToFacebook() +{ + if (!mConnectedToFbc) + { + LLHTTPClient::get(getFacebookConnectURL("/connection"), new FacebookConnectedResponder(this, false)); + } +} + +void LLPanelPeople::connectToFacebook(const std::string& auth_code) +{ + LLSD body; + if (!auth_code.empty()) + body["code"] = auth_code; + + LLHTTPClient::put(getFacebookConnectURL("/connection"), body, new FacebookConnectResponder(this)); +} + +void LLPanelPeople::disconnectFromFacebook() +{ + LLHTTPClient::del(getFacebookConnectURL("/connection"), new FacebookDisconnectResponder(this)); +} + +std::string LLPanelPeople::getFacebookConnectURL(const std::string& route) +{ + static std::string sFacebookConnectUrl = gAgent.getRegion()->getCapability("FacebookConnect"); + std::string url = sFacebookConnectUrl + route; + llinfos << url << llendl; + return url; +} + +void LLPanelPeople::onLoginFbcButtonClicked() +{ + if (mConnectedToFbc) + { + disconnectFromFacebook(); + } + else + { + LLHTTPClient::get(getFacebookConnectURL("/connection"), new FacebookConnectedResponder(this, true)); + } +} + +void LLPanelPeople::onFacebookAppRequestClicked() +{ +} + +void LLPanelPeople::onFacebookAppSendClicked() +{ +} + +static LLFastTimer::DeclareTimer FTM_AVATAR_LIST_TEST("avatar list test"); + +void LLPanelPeople::onFacebookTestAddClicked() +{ + LLFastTimer _(FTM_AVATAR_LIST_TEST); + + mFacebookFriends->clear(); + + LL_INFOS("LLPanelPeople") << "start adding 300 users" << LL_ENDL; + + for(int i = 0; i < 300; ++i) + { + mFacebookFriends->addNewItem(LLUUID(), "Test", false); + } + + LL_INFOS("LLPanelPeople") << "finished adding 300 users" << LL_ENDL; +} + // EOF |