diff options
-rw-r--r-- | indra/newview/llavatarlist.cpp | 76 | ||||
-rw-r--r-- | indra/newview/llavatarlist.h | 8 | ||||
-rw-r--r-- | indra/newview/llavatarlistitem.cpp | 50 | ||||
-rw-r--r-- | indra/newview/llavatarlistitem.h | 6 | ||||
-rw-r--r-- | indra/newview/llchiclet.cpp | 2 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/panel_avatar_list_item.xml | 11 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/panel_people.xml | 1 |
7 files changed, 114 insertions, 40 deletions
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index e93d0dfa50..05a1f75e01 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -37,11 +37,15 @@ // newview #include "llcallingcard.h" // for LLAvatarTracker #include "llcachename.h" +#include "llrecentpeople.h" #include "llvoiceclient.h" #include "llviewercontrol.h" // for gSavedSettings static LLDefaultChildRegistry::Register<LLAvatarList> r("avatar_list"); +// Last interaction time update period. +static const F32 LIT_UPDATE_PERIOD = 5; + // Maximum number of avatars that can be added to a list in one pass. // Used to limit time spent for avatar list update per frame. static const unsigned ADD_LIMIT = 50; @@ -74,19 +78,35 @@ static const LLFlatListView::ItemReverseComparator REVERSE_NAME_COMPARATOR(NAME_ LLAvatarList::Params::Params() : ignore_online_status("ignore_online_status", false) +, show_last_interaction_time("show_last_interaction_time", false) { } LLAvatarList::LLAvatarList(const Params& p) : LLFlatListView(p) , mIgnoreOnlineStatus(p.ignore_online_status) +, mShowLastInteractionTime(p.show_last_interaction_time) , mContextMenu(NULL) , mDirty(true) // to force initial update +, mLITUpdateTimer(NULL) { setCommitOnSelectionChange(true); // Set default sort order. setComparator(&NAME_COMPARATOR); + + if (mShowLastInteractionTime) + { + mLITUpdateTimer = new LLTimer(); + mLITUpdateTimer->setTimerExpirySec(0); // zero to force initial update + mLITUpdateTimer->start(); + } +} + +LLAvatarList::~LLAvatarList() +{ + delete mLITUpdateTimer; + mShowIcons = gSavedSettings.getBOOL(mIconParamName); } void LLAvatarList::setShowIcons(std::string param_name) @@ -105,6 +125,12 @@ void LLAvatarList::draw() if (mDirty) refresh(); + + if (mShowLastInteractionTime && mLITUpdateTimer->hasExpired()) + { + updateLastInteractionTimes(); + mLITUpdateTimer->setTimerExpirySec(LIT_UPDATE_PERIOD); // restart the timer + } } void LLAvatarList::setNameFilter(const std::string& filter) @@ -218,12 +244,12 @@ void LLAvatarList::refresh() void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is_online, EAddPosition pos) { LLAvatarListItem* item = new LLAvatarListItem(); - item->showStatus(false); item->showInfoBtn(true); item->showSpeakingIndicator(true); item->setName(name); item->setAvatarId(id, mIgnoreOnlineStatus); item->setOnline(mIgnoreOnlineStatus ? true : is_online); + item->showLastInteractionTime(mShowLastInteractionTime); item->setContextMenu(mContextMenu); item->childSetVisible("info_btn", false); @@ -279,6 +305,54 @@ void LLAvatarList::computeDifference( vadded.erase(it, vadded.end()); } +static std::string format_secs(S32 secs) +{ + // *TODO: reinventing the wheel? + // *TODO: i18n + static const int LL_AL_MIN = 60; + static const int LL_AL_HOUR = LL_AL_MIN * 60; + static const int LL_AL_DAY = LL_AL_HOUR * 24; + static const int LL_AL_WEEK = LL_AL_DAY * 7; + static const int LL_AL_MONTH = LL_AL_DAY * 31; + static const int LL_AL_YEAR = LL_AL_DAY * 365; + + std::string s; + + if (secs >= LL_AL_YEAR) + s = llformat("%dy", secs / LL_AL_YEAR); + else if (secs >= LL_AL_MONTH) + s = llformat("%dmon", secs / LL_AL_MONTH); + else if (secs >= LL_AL_WEEK) + s = llformat("%dw", secs / LL_AL_WEEK); + else if (secs >= LL_AL_DAY) + s = llformat("%dd", secs / LL_AL_DAY); + else if (secs >= LL_AL_HOUR) + s = llformat("%dh", secs / LL_AL_HOUR); + else if (secs >= LL_AL_MIN) + s = llformat("%dm", secs / LL_AL_MIN); + else + s = llformat("%ds", secs); + + return s; +} + +// Refresh shown time of our last interaction with all listed avatars. +void LLAvatarList::updateLastInteractionTimes() +{ + S32 now = (S32) LLDate::now().secondsSinceEpoch(); + std::vector<LLPanel*> items; + getItems(items); + + for( std::vector<LLPanel*>::const_iterator it = items.begin(); it != items.end(); it++) + { + // *TODO: error handling + LLAvatarListItem* item = static_cast<LLAvatarListItem*>(*it); + S32 secs_since = now - (S32) LLRecentPeople::instance().getDate(item->getAvatarId()).secondsSinceEpoch(); + if (secs_since >= 0) + item->setLastInteractionTime(format_secs(secs_since)); + } +} + bool LLAvatarItemComparator::compare(const LLPanel* item1, const LLPanel* item2) const { const LLAvatarListItem* avatar_item1 = dynamic_cast<const LLAvatarListItem*>(item1); diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h index f60f1f00f3..8f2f0249a6 100644 --- a/indra/newview/llavatarlist.h +++ b/indra/newview/llavatarlist.h @@ -37,6 +37,8 @@ #include "llavatarlistitem.h" +class LLTimer; + /** * Generic list of avatars. * @@ -56,11 +58,12 @@ public: struct Params : public LLInitParam::Block<Params, LLFlatListView::Params> { Optional<bool> ignore_online_status; // show all items as online + Optional<bool> show_last_interaction_time; // show most recent interaction time. *HACK: move this to a derived class Params(); }; LLAvatarList(const Params&); - virtual ~LLAvatarList() {} + virtual ~LLAvatarList(); virtual void draw(); // from LLView @@ -85,13 +88,16 @@ protected: const std::vector<LLUUID>& vnew, std::vector<LLUUID>& vadded, std::vector<LLUUID>& vremoved); + void updateLastInteractionTimes(); private: bool mIgnoreOnlineStatus; + bool mShowLastInteractionTime; bool mDirty; bool mShowIcons; + LLTimer* mLITUpdateTimer; // last interaction time update timer std::string mIconParamName; std::string mNameFilter; uuid_vector_t mIDs; diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index 4ecb9537ba..8464430501 100644 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -48,7 +48,7 @@ LLAvatarListItem::LLAvatarListItem() : LLPanel(), mAvatarIcon(NULL), mAvatarName(NULL), - mStatus(NULL), + mLastInteractionTime(NULL), mSpeakingIndicator(NULL), mInfoBtn(NULL), mProfileBtn(NULL), @@ -74,8 +74,8 @@ BOOL LLAvatarListItem::postBuild() { mAvatarIcon = getChild<LLAvatarIconCtrl>("avatar_icon"); mAvatarName = getChild<LLTextBox>("avatar_name"); - mStatus = getChild<LLTextBox>("avatar_status"); - + mLastInteractionTime = getChild<LLTextBox>("last_interaction"); + mSpeakingIndicator = getChild<LLOutputMonitorCtrl>("speaking_indicator"); mInfoBtn = getChild<LLButton>("info_btn"); mProfileBtn = getChild<LLButton>("profile_btn"); @@ -97,12 +97,6 @@ BOOL LLAvatarListItem::postBuild() rect.setLeftTopAndSize(mName->getRect().mLeft, mName->getRect().mTop, mName->getRect().getWidth() + 30, mName->getRect().getHeight()); mName->setRect(rect); - if(mStatus) - { - rect.setLeftTopAndSize(mStatus->getRect().mLeft + 30, mStatus->getRect().mTop, mStatus->getRect().getWidth(), mStatus->getRect().getHeight()); - mStatus->setRect(rect); - } - if(mLocator) { rect.setLeftTopAndSize(mLocator->getRect().mLeft + 30, mLocator->getRect().mTop, mLocator->getRect().getWidth(), mLocator->getRect().getHeight()); @@ -137,11 +131,6 @@ void LLAvatarListItem::onMouseLeave(S32 x, S32 y, MASK mask) LLPanel::onMouseLeave(x, y, mask); } -void LLAvatarListItem::setStatus(const std::string& status) -{ - mStatus->setValue(status); -} - // virtual, called by LLAvatarTracker void LLAvatarListItem::changed(U32 mask) { @@ -195,6 +184,24 @@ void LLAvatarListItem::setAvatarId(const LLUUID& id, bool ignore_status_changes) gCacheName->get(id, FALSE, boost::bind(&LLAvatarListItem::onNameCache, this, _2, _3)); } +void LLAvatarListItem::showLastInteractionTime(bool show) +{ + if (show) + return; + + LLRect name_rect = mAvatarName->getRect(); + LLRect time_rect = mLastInteractionTime->getRect(); + + mLastInteractionTime->setVisible(false); + name_rect.mRight += (time_rect.mRight - name_rect.mRight); + mAvatarName->setRect(name_rect); +} + +void LLAvatarListItem::setLastInteractionTime(const std::string& val) +{ + mLastInteractionTime->setValue(val); +} + void LLAvatarListItem::setAvatarIconVisible(bool visible) { // Already done? Then do nothing. @@ -240,21 +247,6 @@ void LLAvatarListItem::onProfileBtnClick() LLAvatarActions::showProfile(mAvatarId); } -void LLAvatarListItem::showStatus(bool show_status) -{ - // *HACK: dirty hack until we can determine correct avatar status (EXT-1076). - - if (show_status) - return; - - LLRect name_rect = mAvatarName->getRect(); - LLRect status_rect = mStatus->getRect(); - - mStatus->setVisible(show_status); - name_rect.mRight += (status_rect.mRight - name_rect.mRight); - mAvatarName->setRect(name_rect); -} - void LLAvatarListItem::setValue( const LLSD& value ) { if (!value.isMap()) return;; diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h index a8d3919217..10c0b17005 100644 --- a/indra/newview/llavatarlistitem.h +++ b/indra/newview/llavatarlistitem.h @@ -60,10 +60,10 @@ public: virtual void setValue(const LLSD& value); virtual void changed(U32 mask); // from LLFriendObserver - void setStatus(const std::string& status); void setOnline(bool online); void setName(const std::string& name); void setAvatarId(const LLUUID& id, bool ignore_status_changes = false); + void setLastInteractionTime(const std::string& val); void setAvatarIconVisible(bool visible); const LLUUID& getAvatarId() const; @@ -74,7 +74,7 @@ public: void showSpeakingIndicator(bool show) { mSpeakingIndicator->setVisible(show); } void showInfoBtn(bool show_info_btn) {mInfoBtn->setVisible(show_info_btn); } - void showStatus(bool show_status); + void showLastInteractionTime(bool show); void setContextMenu(ContextMenu* menu) { mContextMenu = menu; } @@ -90,7 +90,7 @@ private: LLAvatarIconCtrl* mAvatarIcon; LLTextBox* mAvatarName; - LLTextBox* mStatus; + LLTextBox* mLastInteractionTime; LLOutputMonitorCtrl* mSpeakingIndicator; LLButton* mInfoBtn; diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index 61a60a24be..4ff360cd74 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -1398,7 +1398,7 @@ void LLTalkButton::onClick_ShowBtn() LLAvatarListItem* item = new LLAvatarListItem(); - item->showStatus(true); + item->showLastInteractionTime(false); item->showInfoBtn(true); item->showSpeakingIndicator(true); item->reshape(mPrivateCallPanel->getRect().getWidth(), item->getRect().getHeight(), FALSE); diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml index f747c557e2..8aaa462aaf 100644 --- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml @@ -47,17 +47,17 @@ top="6" use_ellipses="true" value="Unknown" - width="166" /> + width="196" /> <text - follows="left" + follows="right" font="SansSerifSmall" height="15" layout="topleft" left_pad="10" - name="avatar_status" + name="last_interaction" text_color="LtGray_50" - value="Away" - width="50" /> + value="0s" + width="24" /> <output_monitor auto_update="true" follows="right" @@ -75,6 +75,7 @@ image_pressed="Info_Press" image_hover="Info_Over" image_unselected="Info_Off" + layout="topleft" left_pad="3" right="-25" name="info_btn" diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index 7b19ab1a1c..ec6377c723 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -301,6 +301,7 @@ background_visible="true" left="0" multi_select="true" name="avatar_list" + show_last_interaction_time="true" top="2" width="313" /> <panel |