# Conflicts:
#	indra/newview/app_settings/settings.xml
#	indra/newview/llaisapi.cpp
#	indra/newview/llinventoryobserver.cpp
#	indra/newview/llinventoryobserver.h
#	indra/newview/llsidepanelinventory.cpp
#	indra/newview/skins/default/xui/ja/floater_inventory_item_properties.xml
meow-7.2.2
Ansariel 2023-08-25 02:16:13 +02:00
commit 7c5671465e
22 changed files with 200 additions and 57 deletions

View File

@ -1218,7 +1218,14 @@ LLSD LLInventoryCategory::asAISLLSD() const
S8 type = static_cast<S8>(mPreferredType);
sd[INV_ASSET_TYPE_LABEL_WS] = type;
sd[INV_NAME_LABEL] = mName;
sd[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID);
if (mThumbnailUUID.notNull())
{
sd[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID);
}
else
{
sd[INV_THUMBNAIL_LABEL] = LLSD();
}
return sd;
}

View File

@ -7842,9 +7842,9 @@
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<string>LLSD</string>
<key>Value</key>
<integer>0</integer>
<string></string>
</map>
<key>LastFindPanel</key>
<map>

View File

@ -140,6 +140,9 @@ 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 = 1;
// The agent instance.
LLAgent gAgent;
@ -655,27 +658,84 @@ void LLAgent::setFirstLogin(bool b)
if (mFirstLogin)
{
// Don't notify new users about new features
S32 feature_version = gSavedSettings.getS32("LastUIFeatureVersion");
if (feature_version < UI_FEATURE_VERSION)
if (getFeatureVersion() <= UI_FEATURE_VERSION)
{
gSavedSettings.setS32("LastUIFeatureVersion", UI_FEATURE_VERSION);
setFeatureVersion(UI_FEATURE_VERSION, UI_FEATURE_FLAGS);
}
}
}
void LLAgent::showLatestFeatureNotification()
void LLAgent::setFeatureVersion(S32 version, S32 flags)
{
// Notify user about new thumbnail support
S32 feature_version = gSavedSettings.getS32("LastUIFeatureVersion");
if (feature_version < UI_FEATURE_VERSION)
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())
{
// Need to open on top even if called from onOpen,
// do on idle to make sure it's on top
doOnIdleOneTime([]()
{
LLFloaterReg::showInstance("new_feature_notification");
});
gSavedSettings.setS32("LastUIFeatureVersion", UI_FEATURE_VERSION);
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);
}
}
}

View File

@ -125,7 +125,10 @@ public:
bool isFirstLogin() const { return mFirstLogin; }
bool isInitialized() const { return mInitialized; }
void showLatestFeatureNotification();
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:

View File

@ -994,6 +994,7 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht
}
else if (result.has("item_id"))
{
// Error message might contain an item_id!!!
ids.emplace(result["item_id"]);
}
break;
@ -1044,6 +1045,7 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht
//case FETCHITEM:
// if (result.has("item_id"))
// {
// // Error message might contain an item_id!!!
// id = result["item_id"];
// }
// if (result.has("linked_id"))
@ -1225,11 +1227,15 @@ void AISUpdate::parseMeta(const LLSD& update)
void AISUpdate::parseContent(const LLSD& update)
{
if (update.has("linked_id"))
// Errors from a fetch request might contain id without
// full item or folder.
// Todo: Depending on error we might want to do something,
// like removing a 404 item or refetching parent folder
if (update.has("linked_id") && update.has("parent_id"))
{
parseLink(update, mFetchDepth);
}
else if (update.has("item_id"))
else if (update.has("item_id") && update.has("parent_id"))
{
parseItem(update);
}
@ -1243,7 +1249,7 @@ void AISUpdate::parseContent(const LLSD& update)
parseEmbedded(update["_embedded"], mFetchDepth - 1);
}
}
else if (update.has("category_id"))
else if (update.has("category_id") && update.has("parent_id"))
{
parseCategory(update, mFetchDepth);
}
@ -1699,7 +1705,7 @@ void AISUpdate::doUpdate()
gInventory.updateCategory(new_category, LLInventoryObserver::CREATE);
LL_DEBUGS("Inventory") << "created category " << category_id << LL_ENDL;
// fetching can receive massive amount of items and fodlers
// fetching can receive massive amount of items and folders
if (gInventory.getChangedIDs().size() > MAX_UPDATE_BACKLOG)
{
gInventory.notifyObservers();
@ -1760,7 +1766,7 @@ void AISUpdate::doUpdate()
LL_DEBUGS("Inventory") << "created item " << item_id << LL_ENDL;
gInventory.updateItem(new_item, LLInventoryObserver::CREATE);
// fetching can receive massive amount of items and fodlers
// fetching can receive massive amount of items and folders
if (gInventory.getChangedIDs().size() > MAX_UPDATE_BACKLOG)
{
gInventory.notifyObservers();

View File

@ -788,8 +788,16 @@ void LLFloaterChangeItemThumbnail::setThumbnailId(const LLUUID& new_thumbnail_id
if (obj->getThumbnailUUID() != new_thumbnail_id)
{
LLSD updates;
// At the moment server expects id as a string
updates["thumbnail"] = LLSD().with("asset_id", new_thumbnail_id.asString());
if (new_thumbnail_id.notNull())
{
// At the moment server expects id as a string
updates["thumbnail"] = LLSD().with("asset_id", new_thumbnail_id.asString());
}
else
{
// No thumbnail isntead of 'null id thumbnail'
updates["thumbnail"] = LLSD();
}
LLViewerInventoryCategory* view_folder = dynamic_cast<LLViewerInventoryCategory*>(obj);
if (view_folder)
{

View File

@ -482,11 +482,22 @@ void LLFloaterMarketplaceListings::setRootFolder()
LLStringUtil::null,
[](const LLUUID &new_cat_id)
{
LLFloaterMarketplaceListings *marketplace = LLFloaterReg::findTypedInstance<LLFloaterMarketplaceListings>("marketplace_listings");
LLFloaterMarketplaceListings* marketplace = LLFloaterReg::findTypedInstance<LLFloaterMarketplaceListings>("marketplace_listings");
if (marketplace)
{
// will call setRootFolder again
marketplace->updateView();
if (new_cat_id.notNull())
{
// will call setRootFolder again
marketplace->updateView();
}
// don't update in case of failure, createNewCategory can return
// immediately if cap is missing and will cause a loop
else
{
// unblock
marketplace->mRootFolderCreating = false;
LL_WARNS("SLM") << "Inventory warning: Failed to create marketplace listings folder for a merchant" << LL_ENDL;
}
}
}
);

View File

@ -42,6 +42,14 @@ 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;
}

View File

@ -386,7 +386,7 @@ void LLFloaterSimpleSnapshot::uploadThumbnail(const std::string &file_path, cons
// generate a temp texture file for coroutine
std::string temp_file = gDirUtilp->getTempFilename();
U32 codec = LLImageBase::getCodecFromExtension(gDirUtilp->getExtension(file_path));
if (!LLViewerTextureList::createUploadFile(file_path, temp_file, codec, THUMBNAIL_SNAPSHOT_DIM_MAX, THUMBNAIL_SNAPSHOT_DIM_MIN))
if (!LLViewerTextureList::createUploadFile(file_path, temp_file, codec, THUMBNAIL_SNAPSHOT_DIM_MAX, THUMBNAIL_SNAPSHOT_DIM_MIN, true))
{
LLSD notif_args;
notif_args["REASON"] = LLImage::getLastError().c_str();

View File

@ -140,8 +140,11 @@ void LLTexturePreviewView::draw()
{
LLRect rctClient = getLocalRect();
if (4 == m_Image->getComponents())
gl_rect_2d_checkerboard(rctClient);
if (4 == m_Image->getComponents())
{
const LLColor4 color(.098f, .098f, .098f);
gl_rect_2d(rctClient, color, TRUE);
}
gl_draw_scaled_image(rctClient.mLeft, rctClient.mBottom, rctClient.getWidth(), rctClient.getHeight(), m_Image);
bool isLoading = (!m_Image->isFullyLoaded()) && (m_Image->getDiscardLevel() > 0);

View File

@ -2353,6 +2353,7 @@ void LLInventoryGalleryItem::draw()
LLUIColor border_color = LLUIColorTable::instance().getColor(mSelected ? "MenuItemHighlightBgColor" : "TextFgTentativeColor", LLColor4::white);
LLRect border = getChildView("preview_thumbnail")->getRect();
border.mRight = border.mRight + 1;
border.mTop = border.mTop + 1;
gl_rect_2d(border, border_color.get(), FALSE);
}

View File

@ -822,7 +822,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis()
|| mLastFetchCount != mFetchCount) // if anything was substracted
{
LL_DEBUGS(LOG_INV , "AIS3") << "Total active fetches: " << mLastFetchCount << "->" << last_fetch_count << "->" << mFetchCount
<< ", scheduled fodler fetches: " << (S32)mFetchFolderQueue.size()
<< ", scheduled folder fetches: " << (S32)mFetchFolderQueue.size()
<< ", scheduled item fetches: " << (S32)mFetchItemQueue.size()
<< LL_ENDL;
mLastFetchCount = mFetchCount;
@ -1571,10 +1571,10 @@ void BGFolderHttpHandler::processFailure(LLCore::HttpStatus status, LLCore::Http
while (iter != end)
{
folders.append(*iter);
LLUUID fodler_id = iter->get("folder_id").asUUID();
if (std::find(mRecursiveCatUUIDs.begin(), mRecursiveCatUUIDs.end(), fodler_id) != mRecursiveCatUUIDs.end())
LLUUID folder_id = iter->get("folder_id").asUUID();
if (std::find(mRecursiveCatUUIDs.begin(), mRecursiveCatUUIDs.end(), folder_id) != mRecursiveCatUUIDs.end())
{
recursive_cats.push_back(fodler_id);
recursive_cats.push_back(folder_id);
}
if (folders.size() == (S32)(size / 2))
{

View File

@ -303,8 +303,8 @@ void LLInventoryFetchItemsObserver::startFetch()
LLSD items_llsd;
typedef std::map<LLUUID, uuid_vec_t> requests_by_fodlers_t;
requests_by_fodlers_t requests;
typedef std::map<LLUUID, uuid_vec_t> requests_by_folders_t;
requests_by_folders_t requests;
for (uuid_vec_t::const_iterator it = mIDs.begin(); it < mIDs.end(); ++it)
{
LLViewerInventoryItem* item = gInventory.getItem(*it);
@ -372,12 +372,19 @@ void LLInventoryFetchItemsObserver::startFetch()
if (aisv3)
{
const S32 MAX_INDIVIDUAL_REQUESTS = 10;
for (requests_by_fodlers_t::value_type &folder : requests)
for (requests_by_folders_t::value_type &folder : requests)
{
LLViewerInventoryCategory* cat = gInventory.getCategory(folder.first);
if (folder.second.size() > MAX_INDIVIDUAL_REQUESTS)
{
// requesting one by one will take a while
// do whole folder
if (cat)
{
// Either drop version or use scheduleFolderFetch to force-fetch
// otherwise background fetch will ignore folders with set version
cat->setVersion(LLViewerInventoryCategory::VERSION_UNKNOWN);
}
LLInventoryModelBackgroundFetch::getInstance()->start(folder.first);
}
else
@ -392,7 +399,8 @@ void LLInventoryFetchItemsObserver::startFetch()
}
else if (cat->getViewerDescendentCount() <= folder.second.size())
{
// start fetching whole folder since we need all items
// Start fetching whole folder since we need all items
// Drop version or use scheduleFolderFetch
cat->setVersion(LLViewerInventoryCategory::VERSION_UNKNOWN);
cat->fetch();
@ -831,7 +839,7 @@ bool LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t
{
if(init_name_hash)
{
digest_t item_name_hash = gInventory.hashDirectDescendentNames(cat_id);
digest_t item_name_hash = gInventory.hashDirectDescendentNames(cat_id);
mCategoryMap.insert(category_map_value_t(cat_id,LLCategoryData(cat_id, thumbnail_id, cb, version, current_num_known_descendents,item_name_hash)));
}
else
@ -861,7 +869,7 @@ LLInventoryCategoriesObserver::LLCategoryData::LLCategoryData(
}
LLInventoryCategoriesObserver::LLCategoryData::LLCategoryData(
const LLUUID& cat_id, const LLUUID& thumbnail_id, callback_t cb, S32 version, S32 num_descendents, digest_t& name_hash)
const LLUUID& cat_id, const LLUUID& thumbnail_id, callback_t cb, S32 version, S32 num_descendents, const digest_t& name_hash)
: mCatID(cat_id)
, mCallback(cb)

View File

@ -274,7 +274,7 @@ protected:
struct LLCategoryData
{
LLCategoryData(const LLUUID& cat_id, const LLUUID& thumbnail_id, callback_t cb, S32 version, S32 num_descendents);
LLCategoryData(const LLUUID& cat_id, const LLUUID& thumbnail_id, callback_t cb, S32 version, S32 num_descendents, digest_t& name_hash);
LLCategoryData(const LLUUID& cat_id, const LLUUID& thumbnail_id, callback_t cb, S32 version, S32 num_descendents, const digest_t& name_hash);
callback_t mCallback;
S32 mVersion;
S32 mDescendentsCount;

View File

@ -111,9 +111,9 @@ void LLPanelLandmarkInfo::setInfoType(EInfoType type)
}
// Sets CREATE_LANDMARK infotype and creates landmark at desired folder
void LLPanelLandmarkInfo::setInfoAndCreateLandmark(const LLUUID& fodler_id)
void LLPanelLandmarkInfo::setInfoAndCreateLandmark(const LLUUID& folder_id)
{
setInfoType(CREATE_LANDMARK, fodler_id);
setInfoType(CREATE_LANDMARK, folder_id);
}
void LLPanelLandmarkInfo::setInfoType(EInfoType type, const LLUUID &folder_id)

View File

@ -48,7 +48,7 @@ public:
/*virtual*/ void setInfoType(EInfoType type);
// Sets CREATE_LANDMARK infotype and creates landmark at desired folder
void setInfoAndCreateLandmark(const LLUUID& fodler_id);
void setInfoAndCreateLandmark(const LLUUID& folder_id);
/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);

View File

@ -477,7 +477,7 @@ void LLSidepanelInventory::onOpen(const LLSD& key)
}
#endif
gAgent.showLatestFeatureNotification();
gAgent.showLatestFeatureNotification("inventory");
if(key.size() == 0)
{

View File

@ -100,7 +100,8 @@ void LLThumbnailCtrl::draw()
{
if( mTexturep->getComponents() == 4 )
{
gl_rect_2d_checkerboard( draw_rect, alpha );
const LLColor4 color(.098f, .098f, .098f);
gl_rect_2d( draw_rect, color, TRUE);
}
gl_draw_scaled_image( draw_rect.mLeft, draw_rect.mBottom, draw_rect.getWidth(), draw_rect.getHeight(), mTexturep, UI_VERTEX_COLOR % alpha);

View File

@ -1433,7 +1433,8 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
const std::string& out_filename,
const U8 codec,
const S32 max_image_dimentions,
const S32 min_image_dimentions)
const S32 min_image_dimentions,
bool force_square)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
// Load the image
@ -1472,7 +1473,7 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
return FALSE;
}
// Convert to j2c (JPEG2000) and save the file locally
LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image, max_image_dimentions);
LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image, max_image_dimentions, force_square);
if (compressedImage.isNull())
{
image->setLastError("Couldn't convert the image to jpeg2000.");
@ -1497,10 +1498,20 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
}
// note: modifies the argument raw_image!!!!
LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions)
LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions, bool force_square)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
raw_image->biasedScaleToPowerOfTwo(max_image_dimentions);
if (force_square)
{
S32 biggest_side = llmax(raw_image->getWidth(), raw_image->getHeight());
S32 square_size = raw_image->biasedDimToPowerOfTwo(biggest_side, max_image_dimentions);
raw_image->scale(square_size, square_size);
}
else
{
raw_image->biasedScaleToPowerOfTwo(max_image_dimentions);
}
LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C();
if (gSavedSettings.getBOOL("LosslessJ2CUpload") &&

View File

@ -97,8 +97,11 @@ public:
const std::string& out_filename,
const U8 codec,
const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT,
const S32 min_image_dimentions = 0);
static LLPointer<LLImageJ2C> convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
const S32 min_image_dimentions = 0,
bool force_square = false);
static LLPointer<LLImageJ2C> convertToUploadFile(LLPointer<LLImageRaw> raw_image,
const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT,
bool force_square = false);
static void processImageNotInDatabase( LLMessageSystem *msg, void **user_data );
// <FS:Ansariel> OpenSim compatibility
static void receiveImageHeader(LLMessageSystem *msg, void **user_data);

View File

@ -10492,7 +10492,14 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
// RequestAgentUpdateAppearanceResponder::onRequestRequested()
// assumes that cof version is only updated with server-bake
// appearance messages.
LL_INFOS("Avatar") << "Processing appearance message version " << thisAppearanceVersion << LL_ENDL;
if (isSelf())
{
LL_INFOS("Avatar") << "Processing appearance message version " << thisAppearanceVersion << LL_ENDL;
}
else
{
LL_INFOS("Avatar") << "Processing appearance message for " << getID() << ", version " << thisAppearanceVersion << LL_ENDL;
}
// Note:
// locally the COF is maintained via LLInventoryModel::accountForUpdate

View File

@ -13,6 +13,13 @@
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"
@ -25,7 +32,7 @@
top="10"
right="-10"
name="title_txt">
New inventory features
New feature
</text>
<text
type="string"
@ -39,8 +46,7 @@ New inventory features
right="-10"
word_wrap="true"
name="description_txt">
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]
Feature description
</text>
<button
follows="bottom|left|right"