From 2c999688c4c792630865bd97c2b45ff886d9a26c Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Thu, 12 Aug 2010 15:18:25 -0700
Subject: [PATCH] added remaining hints and fade in/fade out behavior

---
 indra/newview/app_settings/settings.xml       | 33 ++++++++++
 indra/newview/llagent.cpp                     | 21 +++++++
 indra/newview/llagent.h                       |  1 +
 indra/newview/llappviewer.cpp                 |  3 +
 indra/newview/llappviewer.h                   |  1 +
 indra/newview/llfirstuse.cpp                  |  8 ++-
 indra/newview/llfirstuse.h                    |  2 +-
 indra/newview/llhints.cpp                     | 62 +++++++++++++++----
 indra/newview/llmoveview.cpp                  |  2 +
 indra/newview/llnearbychatbar.cpp             |  2 +
 indra/newview/llnearbychathandler.cpp         |  5 +-
 indra/newview/llpanelplaces.cpp               |  3 +
 indra/newview/llsidepanelinventory.cpp        |  4 +-
 indra/newview/llsidetray.cpp                  |  2 +
 indra/newview/llstatusbar.cpp                 |  7 +++
 indra/newview/llviewerwindow.cpp              | 13 ++++
 .../skins/default/xui/en/notifications.xml    | 28 ++++-----
 .../skins/default/xui/en/panel_hint.xml       |  1 +
 18 files changed, 164 insertions(+), 34 deletions(-)

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 3326319e2d5..12fb8741ca6 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -11947,5 +11947,38 @@
       <key>Value</key>
       <integer>10</integer>
     </map>
+    <key>NotMovingHintTimeout</key>
+    <map>
+      <key>Comment</key>
+      <string>Number of seconds to wait for resident to move before displaying move hint.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <real>120.0</real>
+    </map>
+    <key>DestinationGuideHintTimeout</key>
+    <map>
+      <key>Comment</key>
+      <string>Number of seconds to wait before telling resident about destination guide.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <real>600.0</real>
+    </map>
+    <key>SidePanelHintTimeout</key>
+    <map>
+      <key>Comment</key>
+      <string>Number of seconds to wait before telling resident about side panel.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <real>300.0</real>
+    </map>
 </map>
 </llsd>
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index e85d108bb29..0ff88f7451f 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -44,6 +44,7 @@
 #include "llcallingcard.h"
 #include "llchannelmanager.h"
 #include "llconsole.h"
+#include "llfirstuse.h"
 #include "llfloatercamera.h"
 #include "llfloaterreg.h"
 #include "llfloatertools.h"
@@ -306,6 +307,9 @@ void LLAgent::ageChat()
 //-----------------------------------------------------------------------------
 void LLAgent::moveAt(S32 direction, bool reset)
 {
+	mMoveTimer.reset();
+	LLFirstUse::notMoving(false);
+
 	// age chat timer so it fades more quickly when you are intentionally moving
 	ageChat();
 
@@ -331,6 +335,9 @@ void LLAgent::moveAt(S32 direction, bool reset)
 //-----------------------------------------------------------------------------
 void LLAgent::moveAtNudge(S32 direction)
 {
+	mMoveTimer.reset();
+	LLFirstUse::notMoving(false);
+
 	// age chat timer so it fades more quickly when you are intentionally moving
 	ageChat();
 
@@ -353,6 +360,9 @@ void LLAgent::moveAtNudge(S32 direction)
 //-----------------------------------------------------------------------------
 void LLAgent::moveLeft(S32 direction)
 {
+	mMoveTimer.reset();
+	LLFirstUse::notMoving(false);
+
 	// age chat timer so it fades more quickly when you are intentionally moving
 	ageChat();
 
@@ -375,6 +385,9 @@ void LLAgent::moveLeft(S32 direction)
 //-----------------------------------------------------------------------------
 void LLAgent::moveLeftNudge(S32 direction)
 {
+	mMoveTimer.reset();
+	LLFirstUse::notMoving(false);
+
 	// age chat timer so it fades more quickly when you are intentionally moving
 	ageChat();
 
@@ -397,6 +410,9 @@ void LLAgent::moveLeftNudge(S32 direction)
 //-----------------------------------------------------------------------------
 void LLAgent::moveUp(S32 direction)
 {
+	mMoveTimer.reset();
+	LLFirstUse::notMoving(false);
+
 	// age chat timer so it fades more quickly when you are intentionally moving
 	ageChat();
 
@@ -1534,6 +1550,11 @@ void LLAgent::propagate(const F32 dt)
 //-----------------------------------------------------------------------------
 void LLAgent::updateAgentPosition(const F32 dt, const F32 yaw_radians, const S32 mouse_x, const S32 mouse_y)
 {
+	if (mMoveTimer.getElapsedTimeF32() > gSavedSettings.getF32("NotMovingHintTimeout"))
+	{
+		LLFirstUse::notMoving();
+	}
+
 	propagate(dt);
 
 	// static S32 cameraUpdateCount = 0;
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 32f9b001356..0185f874f96 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -270,6 +270,7 @@ class LLAgent : public LLOldEvents::LLObservable
 private:
 	LLFrameTimer	mFidgetTimer;
 	LLFrameTimer	mFocusObjectFadeTimer;
+	LLFrameTimer	mMoveTimer;
 	F32				mNextFidgetTime;
 	S32				mCurrentFidget;
 
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index d222d94ec60..768be116f6d 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -268,6 +268,7 @@ const F64 FRAME_STALL_THRESHOLD = 1.0;
 
 LLTimer gRenderStartTime;
 LLFrameTimer gForegroundTime;
+LLFrameTimer gLoggedInTime;
 LLTimer gLogoutTimer;
 static const F32 LOGOUT_REQUEST_TIME = 6.f;  // this will be cut short by the LogoutReply msg.
 F32 gLogoutMaxTime = LOGOUT_REQUEST_TIME;
@@ -597,6 +598,7 @@ LLAppViewer::LLAppViewer() :
 
 	setupErrorHandling();
 	sInstance = this;
+	gLoggedInTime.stop();
 }
 
 LLAppViewer::~LLAppViewer()
@@ -4281,6 +4283,7 @@ void LLAppViewer::pingMainloopTimeout(const std::string& state, F32 secs)
 
 void LLAppViewer::handleLoginComplete()
 {
+	gLoggedInTime.start();
 	initMainloopTimeout("Mainloop Init");
 
 	// Store some data to DebugInfo in case of a freeze.
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 0b862a92a1a..e5e27dc9089 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -313,6 +313,7 @@ extern U32 		gFrameStalls;
 
 extern LLTimer gRenderStartTime;
 extern LLFrameTimer gForegroundTime;
+extern LLFrameTimer gLoggedInTime;
 
 extern F32 gLogoutMaxTime;
 extern LLTimer gLogoutTimer;
diff --git a/indra/newview/llfirstuse.cpp b/indra/newview/llfirstuse.cpp
index d2dff499048..4708087846a 100644
--- a/indra/newview/llfirstuse.cpp
+++ b/indra/newview/llfirstuse.cpp
@@ -90,7 +90,7 @@ void LLFirstUse::useOverrideKeys()
 }
 
 // static
-void LLFirstUse::otherAvatarChat(bool enable)
+void LLFirstUse::otherAvatarChatFirst(bool enable)
 {
 	firstUseNotification("FirstOtherChatBeforeUser", enable, "HintChat", LLSD(), LLSD().with("target", "nearby_chat_bar").with("direction", "top"));
 }
@@ -116,13 +116,15 @@ void LLFirstUse::useSandbox()
 // static
 void LLFirstUse::notUsingDestinationGuide(bool enable)
 {
-	firstUseNotification("FirstNotUseDestinationGuide", enable, "HintDestinationGuide", LLSD(), LLSD().with("target", "dest_guide_btn").with("direction", "left"));
+	// not doing this yet
+	//firstUseNotification("FirstNotUseDestinationGuide", enable, "HintDestinationGuide", LLSD(), LLSD().with("target", "dest_guide_btn").with("direction", "left"));
 }
 
 // static
 void LLFirstUse::notUsingSidePanel(bool enable)
 {
-	firstUseNotification("FirstNotUseSidePanel", enable, "HintSidePanel", LLSD(), LLSD().with("target", "side_panel_btn").with("direction", "left"));
+	// not doing this yet
+	//firstUseNotification("FirstNotUseSidePanel", enable, "HintSidePanel", LLSD(), LLSD().with("target", "side_panel_btn").with("direction", "left"));
 }
 
 // static
diff --git a/indra/newview/llfirstuse.h b/indra/newview/llfirstuse.h
index abf7d9836ea..48943cd9ab1 100644
--- a/indra/newview/llfirstuse.h
+++ b/indra/newview/llfirstuse.h
@@ -91,7 +91,7 @@ class LLFirstUse
 	static void resetFirstUse();
 
 	static void useOverrideKeys();
-	static void otherAvatarChat(bool enable = true);
+	static void otherAvatarChatFirst(bool enable = true);
 	static void sit(bool enable = true);
 	static void notUsingDestinationGuide(bool enable = true);
 	static void notUsingSidePanel(bool enable = true);
diff --git a/indra/newview/llhints.cpp b/indra/newview/llhints.cpp
index 2f3504efed1..66799535c14 100644
--- a/indra/newview/llhints.cpp
+++ b/indra/newview/llhints.cpp
@@ -72,7 +72,13 @@ class LLHintPopup : public LLPanel
 		Optional<LLUIImage*>			left_arrow,
 										up_arrow,
 										right_arrow,
-										down_arrow;									
+										down_arrow;	
+		Optional<S32>					left_arrow_offset,
+										up_arrow_offset,
+										right_arrow_offset,
+										down_arrow_offset;
+		Optional<F32>					fade_in_time,
+										fade_out_time;
 
 		Params()
 		:	direction("direction", TOP),
@@ -81,7 +87,13 @@ class LLHintPopup : public LLPanel
 			left_arrow("left_arrow", LLUI::getUIImage("hint_arrow_left")),
 			up_arrow("up_arrow", LLUI::getUIImage("hint_arrow_up")),
 			right_arrow("right_arrow", LLUI::getUIImage("hint_arrow_right")),
-			down_arrow("down_arrow", LLUI::getUIImage("hint_arrow_down"))
+			down_arrow("down_arrow", LLUI::getUIImage("hint_arrow_down")),
+			left_arrow_offset("left_arrow_offset", 3),
+			up_arrow_offset("up_arrow_offset", -2),
+			right_arrow_offset("right_arrow_offset", -3),
+			down_arrow_offset("down_arrow_offset", 5),
+			fade_in_time("fade_in_time", 0.2f),
+			fade_out_time("fade_out_time", 0.5f)
 		{}
 	};
 
@@ -92,7 +104,7 @@ class LLHintPopup : public LLPanel
 
 	void onClickClose() { hide(); }
 	void draw();
-	void hide() { die(); }
+	void hide() { mHidden = true; mFadeTimer.reset(); }
 
 private:
 	LLNotificationPtr	mNotification;
@@ -103,6 +115,14 @@ class LLHintPopup : public LLPanel
 						mArrowUp,
 						mArrowRight,
 						mArrowDown;
+	S32					mArrowLeftOffset,
+						mArrowUpOffset,
+						mArrowRightOffset,
+						mArrowDownOffset;
+	LLFrameTimer		mFadeTimer;
+	F32					mFadeInTime,
+						mFadeOutTime;
+	bool				mHidden;
 };
 
 
@@ -117,6 +137,13 @@ LLHintPopup::LLHintPopup(const LLHintPopup::Params& p)
 	mArrowUp(p.up_arrow),
 	mArrowRight(p.right_arrow),
 	mArrowDown(p.down_arrow),
+	mArrowLeftOffset(p.left_arrow_offset),
+	mArrowUpOffset(p.up_arrow_offset),
+	mArrowRightOffset(p.right_arrow_offset),
+	mArrowDownOffset(p.down_arrow_offset),
+	mHidden(false),
+	mFadeInTime(p.fade_in_time),
+	mFadeOutTime(p.fade_out_time),
 	LLPanel(p)
 {
 	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_hint.xml");
@@ -138,6 +165,17 @@ BOOL LLHintPopup::postBuild()
 
 void LLHintPopup::draw()
 {
+	F32 alpha = 1.f;
+	if (mHidden)
+	{
+		alpha = clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, mFadeOutTime, 1.f, 0.f);
+	}
+	else
+	{
+		alpha = clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, mFadeInTime, 0.f, 1.f);
+	}
+	LLViewDrawContext context(alpha);
+
 	LLView* targetp = mTarget.get();
 	if (!targetp || !targetp->isInVisibleChain()) 
 	{
@@ -153,8 +191,6 @@ void LLHintPopup::draw()
 		LLRect arrow_rect;
 		LLUIImagePtr arrow_imagep;
 
-		const S32 OVERLAP = 5;
-
 		switch(mDirection)
 		{
 		case LEFT:
@@ -162,7 +198,7 @@ void LLHintPopup::draw()
 										target_rect.getCenterY(), 
 										my_local_rect.getWidth(), 
 										my_local_rect.getHeight());
-			arrow_rect.setCenterAndSize(my_local_rect.mRight + mArrowRight->getWidth() / 2 - OVERLAP,
+			arrow_rect.setCenterAndSize(my_local_rect.mRight + mArrowRight->getWidth() / 2 + mArrowRightOffset,
 										my_local_rect.getCenterY(),
 										mArrowRight->getWidth(), 
 										mArrowRight->getHeight());
@@ -174,7 +210,7 @@ void LLHintPopup::draw()
 										my_local_rect.getWidth(), 
 										my_local_rect.getHeight());
 			arrow_rect.setCenterAndSize(my_local_rect.getCenterX(),
-										my_local_rect.mBottom - mArrowDown->getHeight() / 2 + OVERLAP,
+										my_local_rect.mBottom - mArrowDown->getHeight() / 2 + mArrowDownOffset,
 										mArrowDown->getWidth(), 
 										mArrowDown->getHeight());
 			arrow_imagep = mArrowDown;
@@ -184,19 +220,19 @@ void LLHintPopup::draw()
 										target_rect.mTop - (my_local_rect.getHeight() / 2 + mDistance), 
 										my_local_rect.getWidth(), 
 										my_local_rect.getHeight());
-			arrow_rect.setCenterAndSize(my_local_rect.mLeft - mArrowLeft->getWidth() / 2 + OVERLAP,
+			arrow_rect.setCenterAndSize(my_local_rect.mLeft - mArrowLeft->getWidth() / 2 + mArrowLeftOffset,
 										my_local_rect.getCenterY(),
 										mArrowLeft->getWidth(), 
 										mArrowLeft->getHeight());
 			arrow_imagep = mArrowLeft;
 			break;
 		case BOTTOM:
-			my_rect.setCenterAndSize(	target_rect.mLeft + (my_local_rect.getWidth() / 2 + mDistance), 
-										target_rect.getCenterY(), 
+			my_rect.setCenterAndSize(	target_rect.getCenterX(), 
+										target_rect.mBottom - (my_local_rect.getHeight() / 2 + mDistance),
 										my_local_rect.getWidth(), 
 										my_local_rect.getHeight());
 			arrow_rect.setCenterAndSize(my_local_rect.getCenterX(),
-										my_local_rect.mTop + mArrowUp->getHeight() / 2 - OVERLAP,
+										my_local_rect.mTop + mArrowUp->getHeight() / 2 + mArrowUpOffset,
 										mArrowUp->getWidth(), 
 										mArrowUp->getHeight());
 			arrow_imagep = mArrowUp;
@@ -205,7 +241,7 @@ void LLHintPopup::draw()
 		setShape(my_rect);
 		LLPanel::draw();
 
-		arrow_imagep->draw(arrow_rect);
+		arrow_imagep->draw(arrow_rect, LLColor4(1.f, 1.f, 1.f, alpha));
 	}
 }
 
@@ -217,7 +253,7 @@ std::map<LLNotificationPtr, class LLHintPopup*> LLHints::sHints;
 void LLHints::show(LLNotificationPtr hint)
 {
 	LLHintPopup::Params p;
-	LLParamSDParser::instance().readSD(hint->getPayload(), p);
+	LLParamSDParser::instance().readSD(hint->getPayload(), p);
 
 	p.notification = hint;
 
diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp
index 19615def931..148a5786cba 100644
--- a/indra/newview/llmoveview.cpp
+++ b/indra/newview/llmoveview.cpp
@@ -169,6 +169,7 @@ void LLFloaterMove::setVisible(BOOL visible)
 
 	if (visible)
 	{
+		LLFirstUse::notMoving(false);
 		// Attach the Stand/Stop Flying panel.
 		LLPanelStandStopFlying* ssf_panel = LLPanelStandStopFlying::getInstance();
 		ssf_panel->reparent(this);
@@ -571,6 +572,7 @@ void LLPanelStandStopFlying::setStandStopFlyingMode(EStandStopFlyingMode mode)
 	if (mode == SSFM_STAND)
 	{
 		LLFirstUse::sit();
+		LLFirstUse::notMoving(false);
 	}
 	panel->mStandButton->setVisible(SSFM_STAND == mode);
 	panel->mStopFlyingButton->setVisible(SSFM_STOP_FLYING == mode);
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
index 6cfd810c108..41a19a54a84 100644
--- a/indra/newview/llnearbychatbar.cpp
+++ b/indra/newview/llnearbychatbar.cpp
@@ -38,6 +38,7 @@
 #include "llfloaterreg.h"
 #include "lltrans.h"
 
+#include "llfirstuse.h"
 #include "llnearbychatbar.h"
 #include "llbottomtray.h"
 #include "llagent.h"
@@ -490,6 +491,7 @@ BOOL LLNearbyChatBar::matchChatTypeTrigger(const std::string& in_str, std::strin
 
 void LLNearbyChatBar::onChatBoxKeystroke(LLLineEditor* caller, void* userdata)
 {
+	LLFirstUse::otherAvatarChatFirst(false);
 
 	LLNearbyChatBar* self = (LLNearbyChatBar *)userdata;
 
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
index 31a59146d6f..4011552112e 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llnearbychathandler.cpp
@@ -350,7 +350,10 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, const LLSD &args)
 	if(chat_msg.mSourceType == CHAT_SOURCE_AGENT && chat_msg.mFromID.notNull())
 	{
         LLRecentPeople::instance().add(chat_msg.mFromID);
-	 	LLFirstUse::otherAvatarChat();
+		if (chat_msg.mFromID != gAgentID)
+		{
+	 		LLFirstUse::otherAvatarChatFirst();
+		}
 	}
 
 	if(chat_msg.mText.empty())
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index abf2b94b09e..c8a9176d929 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -42,6 +42,7 @@
 
 #include "llcombobox.h"
 #include "llfiltereditor.h"
+#include "llfirstuse.h"
 #include "llfloaterreg.h"
 #include "llnotificationsutil.h"
 #include "lltabcontainer.h"
@@ -351,6 +352,8 @@ BOOL LLPanelPlaces::postBuild()
 
 void LLPanelPlaces::onOpen(const LLSD& key)
 {
+	LLFirstUse::notUsingDestinationGuide(false);
+
 	if (!mPlaceProfile || !mLandmarkInfo)
 		return;
 
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index 7eda4fad205..f9189bfb224 100644
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -129,6 +129,8 @@ BOOL LLSidepanelInventory::postBuild()
 
 void LLSidepanelInventory::onOpen(const LLSD& key)
 {
+	LLFirstUse::inventoryOffer(false);
+
 	if(key.size() == 0)
 		return;
 
@@ -149,8 +151,6 @@ void LLSidepanelInventory::onOpen(const LLSD& key)
 			mTaskPanel->setObjectSelection(LLSelectMgr::getInstance()->getSelection());
 		showTaskInfoPanel();
 	}
-
-	LLFirstUse::inventoryOffer(false);
 }
 
 void LLSidepanelInventory::onInfoButtonClicked()
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index 7e8dc2747b2..7cfc7748830 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -37,6 +37,7 @@
 #include "llagentcamera.h"
 #include "llappviewer.h"
 #include "llbottomtray.h"
+#include "llfirstuse.h"
 #include "llhints.h"
 #include "llsidetray.h"
 #include "llviewerwindow.h"
@@ -470,6 +471,7 @@ void		LLSideTray::onTabButtonClick(string name)
 
 void		LLSideTray::onToggleCollapse()
 {
+	LLFirstUse::notUsingSidePanel(false);
 	if(mCollapsed)
 	{
 		expandSideBar();
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index 46d148c0884..6a081a573e6 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -39,6 +39,7 @@
 #include "llagentcamera.h"
 #include "llbutton.h"
 #include "llcommandhandler.h"
+#include "llfirstuse.h"
 #include "llviewercontrol.h"
 #include "llfloaterbuycurrency.h"
 #include "llbuycurrencyhtml.h"
@@ -341,6 +342,11 @@ void LLStatusBar::creditBalance(S32 credit)
 
 void LLStatusBar::setBalance(S32 balance)
 {
+	if (balance > getBalance() && getBalance() != 0)
+	{
+		LLFirstUse::receiveLindens();
+	}
+
 	std::string money_str = LLResMgr::getInstance()->getMonetaryString( balance );
 
 	LLTextBox* balance_box = getChild<LLTextBox>("balance");
@@ -463,6 +469,7 @@ void LLStatusBar::onClickBuyCurrency()
 	// open a currency floater - actual one open depends on 
 	// value specified in settings.xml
 	LLBuyCurrencyHTML::openCurrencyFloater();
+	LLFirstUse::receiveLindens(false);
 }
 
 void LLStatusBar::onMouseEnterVolume()
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 566f4b45ba8..cfb8b077e58 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -102,6 +102,7 @@
 #include "llface.h"
 #include "llfeaturemanager.h"
 #include "llfilepicker.h"
+#include "llfirstuse.h"
 #include "llfloater.h"
 #include "llfloaterbuildoptions.h"
 #include "llfloaterbuyland.h"
@@ -2423,6 +2424,18 @@ void LLViewerWindow::updateUI()
 
 	static std::string last_handle_msg;
 
+	if (gLoggedInTime.getStarted())
+	{
+		if (gLoggedInTime.getElapsedTimeF32() > gSavedSettings.getF32("DestinationGuideHintTimeout"))
+		{
+			LLFirstUse::notUsingDestinationGuide();
+		}
+		if (gLoggedInTime.getElapsedTimeF32() > gSavedSettings.getF32("SidePanelHintTimeout"))
+		{
+			LLFirstUse::notUsingSidePanel();
+		}
+	}
+
 	LLConsole::updateClass();
 
 	// animate layout stacks so we have up to date rect for world view
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 8db89a76220..a2d06f77a9e 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -6386,53 +6386,53 @@ Mute everyone?
 
   <notification
   name="HintChat"
-  label="Hint for Chatting"
+  label="Chat"
   type="hint">
-    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam
+    To join the conversation, type into the chat field below.
   </notification>
 
   <notification
   name="HintSit"
-  label="Hint for Sitting"
+  label="Stand"
   type="hint">
-    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam
+    To stand up and exit the sitting position, click the Stand button.
   </notification>
   
   <notification
   name="HintDestinationGuide"
-  label="Hint for Destination Guide"
+  label="Explore the World"
   type="hint">
-    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam
+    The Destination Guide contains thousands of new places to discover. Select a location and choose Teleport to start exploring.
   </notification>
   
   <notification
     name="HintSidePanel"
-    label="Hint for Side Panel"
+    label="Side Panel"
     type="hint">
-    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam
+    Get quick access to your inventory, outfits, profiles and more in the side panel.
     <!--<unique/>-->
   </notification>
 
   <notification
   name="HintMove"
-  label="Hint for Movement"
+  label="Move"
   type="hint">
-    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam
+    To walk or run, open the Move Panel and use the directional arrows to navigate. You can also use the directional keys on your keyboard.
     <!--<unique/>-->
   </notification>
 
   <notification
   name="HintInventory"
-  label="Hint for Inventory"
+  label="Inventory"
   type="hint">
-    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam
+    Check your inventory to find items. Newest items can be easily found in the Recent tab.
   </notification>
 
   <notification
   name="HintLindenDollar"
-  label="Hint for L$"
+  label="You've got Linden Dollars!"
   type="hint">
-    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam
+    Here's your current balance of L$. Click Buy L$ to purchase more Linden Dollars.
   </notification>
 
   <global name="UnsupportedCPU">
diff --git a/indra/newview/skins/default/xui/en/panel_hint.xml b/indra/newview/skins/default/xui/en/panel_hint.xml
index 7cb8f58c37d..54ea08e5d43 100644
--- a/indra/newview/skins/default/xui/en/panel_hint.xml
+++ b/indra/newview/skins/default/xui/en/panel_hint.xml
@@ -29,6 +29,7 @@
           width="16" 
           height="16"
           name="close" 
+          follows="right|top" 
           image_unselected="Icon_Close_Foreground"
           image_selected="Icon_Close_Press"/>
 </panel>
-- 
GitLab