SL-20145 New inventory feature notification

Pulled in relevant parts from SL-19929
master
Andrey Kleshchev 2023-06-29 23:53:22 +03:00 committed by akleshchev
parent 311f62f4fa
commit 0b85c05f8e
9 changed files with 309 additions and 10 deletions

View File

@ -246,6 +246,7 @@ set(viewer_SOURCE_FILES
llfloatermyscripts.cpp
llfloatermyenvironment.cpp
llfloaternamedesc.cpp
llfloaternewfeaturenotification.cpp
llfloaternotificationsconsole.cpp
llfloaternotificationstabbed.cpp
llfloateroutfitphotopreview.cpp
@ -895,6 +896,7 @@ set(viewer_HEADER_FILES
llfloatermyscripts.h
llfloatermyenvironment.h
llfloaternamedesc.h
llfloaternewfeaturenotification.h
llfloaternotificationsconsole.h
llfloaternotificationstabbed.h
llfloateroutfitphotopreview.h

View File

@ -5519,6 +5519,17 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>LastUIFeatureVersion</key>
<map>
<key>Comment</key>
<string>UI Feature Version number for tracking feature notification between viewer builds</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>LLSD</string>
<key>Value</key>
<string></string>
</map>
<key>LastFindPanel</key>
<map>
<key>Comment</key>

View File

@ -120,6 +120,11 @@ const F64 CHAT_AGE_FAST_RATE = 3.0;
const F32 MIN_FIDGET_TIME = 8.f; // seconds
const F32 MAX_FIDGET_TIME = 20.f; // seconds
const S32 UI_FEATURE_VERSION = 1;
// For version 1: 1 - inventory, 2 - gltf
// Will need to change to 3 once either inventory or gltf releases and cause a conflict
const S32 UI_FEATURE_FLAGS = 2;
// The agent instance.
LLAgent gAgent;
@ -372,7 +377,7 @@ LLAgent::LLAgent() :
mHideGroupTitle(FALSE),
mGroupID(),
mInitialized(FALSE),
mInitialized(false),
mListener(),
mDoubleTapRunTimer(),
@ -447,7 +452,7 @@ LLAgent::LLAgent() :
mNextFidgetTime(0.f),
mCurrentFidget(0),
mFirstLogin(FALSE),
mFirstLogin(false),
mOutfitChosen(FALSE),
mVoiceConnected(false),
@ -504,7 +509,7 @@ void LLAgent::init()
mHttpPolicy = app_core_http.getPolicy(LLAppCoreHttp::AP_AGENT);
mInitialized = TRUE;
mInitialized = true;
}
//-----------------------------------------------------------------------------
@ -559,6 +564,93 @@ void LLAgent::onAppFocusGained()
}
}
void LLAgent::setFirstLogin(bool b)
{
mFirstLogin = b;
if (mFirstLogin)
{
// Don't notify new users about new features
if (getFeatureVersion() <= UI_FEATURE_VERSION)
{
setFeatureVersion(UI_FEATURE_VERSION, UI_FEATURE_FLAGS);
}
}
}
void LLAgent::setFeatureVersion(S32 version, S32 flags)
{
LLSD updated_version;
updated_version["version"] = version;
updated_version["flags"] = flags;
gSavedSettings.setLLSD("LastUIFeatureVersion", updated_version);
}
S32 LLAgent::getFeatureVersion()
{
S32 version;
S32 flags;
getFeatureVersionAndFlags(version, flags);
return version;
}
void LLAgent::getFeatureVersionAndFlags(S32& version, S32& flags)
{
version = 0;
flags = 0;
LLSD feature_version = gSavedSettings.getLLSD("LastUIFeatureVersion");
if (feature_version.isInteger())
{
version = feature_version.asInteger();
flags = 1; // inventory flag
}
else if (feature_version.isMap())
{
version = feature_version["version"];
flags = feature_version["flags"];
}
else if (!feature_version.isString() && !feature_version.isUndefined())
{
// is something newer inside?
version = UI_FEATURE_VERSION;
flags = UI_FEATURE_FLAGS;
}
}
void LLAgent::showLatestFeatureNotification(const std::string key)
{
S32 version;
S32 flags; // a single release can have multiple new features
getFeatureVersionAndFlags(version, flags);
if (version <= UI_FEATURE_VERSION && (flags & UI_FEATURE_FLAGS) != UI_FEATURE_FLAGS)
{
S32 flag = 0;
if (key == "inventory")
{
// Notify user about new thumbnail support
flag = 1;
}
if (key == "gltf")
{
flag = 2;
}
if ((flags & flag) == 0)
{
// Need to open on top even if called from onOpen,
// do on idle to make sure it's on top
LLSD floater_key(key);
doOnIdleOneTime([floater_key]()
{
LLFloaterReg::showInstance("new_feature_notification", floater_key);
});
setFeatureVersion(UI_FEATURE_VERSION, flags | flag);
}
}
}
void LLAgent::ageChat()
{

View File

@ -117,15 +117,20 @@ private:
//--------------------------------------------------------------------
public:
void onAppFocusGained();
void setFirstLogin(BOOL b) { mFirstLogin = b; }
void setFirstLogin(bool b);
// Return TRUE if the database reported this login as the first for this particular user.
BOOL isFirstLogin() const { return mFirstLogin; }
BOOL isInitialized() const { return mInitialized; }
bool isFirstLogin() const { return mFirstLogin; }
bool isInitialized() const { return mInitialized; }
void setFeatureVersion(S32 version, S32 flags);
S32 getFeatureVersion();
void getFeatureVersionAndFlags(S32 &version, S32 &flags);
void showLatestFeatureNotification(const std::string key);
public:
std::string mMOTD; // Message of the day
private:
BOOL mInitialized;
BOOL mFirstLogin;
bool mInitialized;
bool mFirstLogin;
boost::shared_ptr<LLAgentListener> mListener;
//--------------------------------------------------------------------

View File

@ -0,0 +1,76 @@
/**
* @file llfloaternewfeaturenotification.cpp
* @brief LLFloaterNewFeatureNotification class implementation
*
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2023, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloaternewfeaturenotification.h"
LLFloaterNewFeatureNotification::LLFloaterNewFeatureNotification(const LLSD& key)
: LLFloater(key)
{
}
LLFloaterNewFeatureNotification::~LLFloaterNewFeatureNotification()
{
}
BOOL LLFloaterNewFeatureNotification::postBuild()
{
setCanDrag(FALSE);
getChild<LLButton>("close_btn")->setCommitCallback(boost::bind(&LLFloaterNewFeatureNotification::onCloseBtn, this));
const std::string title_txt = "title_txt";
const std::string dsc_txt = "description_txt";
std::string feature = "_" + getKey().asString();
getChild<LLUICtrl>(title_txt)->setValue(getString(title_txt + feature));
getChild<LLUICtrl>(dsc_txt)->setValue(getString(dsc_txt + feature));
return TRUE;
}
void LLFloaterNewFeatureNotification::onOpen(const LLSD& key)
{
centerOnScreen();
}
void LLFloaterNewFeatureNotification::onCloseBtn()
{
closeFloater();
}
void LLFloaterNewFeatureNotification::centerOnScreen()
{
LLVector2 window_size = LLUI::getInstance()->getWindowSize();
centerWithin(LLRect(0, 0, ll_round(window_size.mV[VX]), ll_round(window_size.mV[VY])));
LLFloaterView* parent = dynamic_cast<LLFloaterView*>(getParent());
if (parent)
{
parent->bringToFront(this);
}
}

View File

@ -0,0 +1,49 @@
/**
* @file llfloaternewfeaturenotification.h
* @brief LLFloaterNewFeatureNotification class definition
*
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2023, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_FLOATER_NEW_FEATURE_NOTOFICATION_H
#define LL_FLOATER_NEW_FEATURE_NOTOFICATION_H
#include "llfloater.h"
class LLFloaterNewFeatureNotification:
public LLFloater
{
friend class LLFloaterReg;
public:
BOOL postBuild() override;
void onOpen(const LLSD& key) override;
private:
LLFloaterNewFeatureNotification(const LLSD& key);
/*virtual*/ ~LLFloaterNewFeatureNotification();
void centerOnScreen();
void onCloseBtn();
};
#endif

View File

@ -3617,7 +3617,7 @@ bool process_login_success_response()
std::string flag = login_flags["ever_logged_in"];
if(!flag.empty())
{
gAgent.setFirstLogin((flag == "N") ? TRUE : FALSE);
gAgent.setFirstLogin(flag == "N");
}
/* Flag is currently ignored by the viewer.
@ -3708,7 +3708,7 @@ bool process_login_success_response()
std::string fake_initial_outfit_name = gSavedSettings.getString("FakeInitialOutfitName");
if (!fake_initial_outfit_name.empty())
{
gAgent.setFirstLogin(TRUE);
gAgent.setFirstLogin(true);
sInitialOutfit = fake_initial_outfit_name;
if (sInitialOutfitGender.empty())
{

View File

@ -98,6 +98,7 @@
#include "llfloatermyscripts.h"
#include "llfloatermyenvironment.h"
#include "llfloaternamedesc.h"
#include "llfloaternewfeaturenotification.h"
#include "llfloaternotificationsconsole.h"
#include "llfloaternotificationstabbed.h"
#include "llfloaterobjectweights.h"
@ -229,6 +230,7 @@ public:
"avatar_picker",
"camera",
"camera_presets",
"change_item_thumbnail"
"classified",
"add_landmark",
"delete_pref_preset",
@ -247,6 +249,7 @@ public:
"message_critical", // Modal!!! Login specific. If this is in use elsewhere, better to create a non modal variant
"message_tos", // Modal!!! Login specific.
"mute_object_by_name",
"new_feature_notification",
"publish_classified",
"save_pref_preset",
"save_camera_preset",
@ -395,6 +398,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("moveview", "floater_moveview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMove>);
LLFloaterReg::add("mute_object_by_name", "floater_mute_object.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGetBlockedObjectName>);
LLFloaterReg::add("mini_map", "floater_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMap>);
LLFloaterReg::add("new_feature_notification", "floater_new_feature_notification.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNewFeatureNotification>);
LLFloaterReg::add("notifications_console", "floater_notifications_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotificationConsole>);

View File

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
height="130"
width="300"
layout="topleft"
name="floater_new_feature_notification"
title="NEW FEATURE"
show_title="false"
header_height="0"
bg_opaque_image="Window_NoTitle_Foreground"
bg_alpha_image="Window_NoTitle_Background"
can_resize="false"
can_drag_on_left="false"
can_minimize="false"
can_close="false">
<floater.string name="title_txt_inventory">
New inventory features
</floater.string>
<floater.string name="description_txt_inventory">
You can now add preview images to inventory items and view a folder in its own window.
Learn more in this [https://community.secondlife.com/blogs/entry/13637-new-features-inventory-item-preview-and-single-folder-view/ blogpost]
</floater.string>
<text
type="string"
length="1"
follows="top|left|right"
font="SansSerifLargeBold"
text_color="White"
layout="topleft"
left="10"
height="14"
top="10"
right="-10"
name="title_txt">
New feature
</text>
<text
type="string"
length="1"
follows="top|left|right"
text_color="White"
layout="topleft"
left="10"
height="40"
top_pad="14"
right="-10"
word_wrap="true"
name="description_txt">
Feature description
</text>
<button
follows="bottom|left|right"
layout="topleft"
height="24"
label="Got it!"
left="104"
bottom="-10"
name="close_btn"
width="90"/>
</floater>