diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp index 33208767f..07b626de9 100644 --- a/indra/newview/llfloateroutbox.cpp +++ b/indra/newview/llfloateroutbox.cpp @@ -86,7 +86,7 @@ public: if (added_category_type == LLFolderType::FT_OUTBOX) { - mOutboxFloater->setupOutbox(added_category->getUUID()); + mOutboxFloater->initializeMarketPlace(); } } } @@ -152,13 +152,17 @@ BOOL LLFloaterOutbox::postBuild() // // Set up the outbox inventory view // - mOutboxInventoryPanel = getChild("panel_outbox_inventory"); + llassert(mOutboxInventoryPanel); mOutboxTopLevelDropZone = getChild("outbox_generic_drag_target"); LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLFloaterOutbox::onFocusReceived, this)); + // Observe category creation to catch outbox creation (moot if already existing) + mCategoryAddedObserver = new LLOutboxAddedObserver(this); + gInventory.addObserver(mCategoryAddedObserver); + return TRUE; } @@ -179,34 +183,26 @@ void LLFloaterOutbox::onClose(bool app_quitting) void LLFloaterOutbox::onOpen() { // - // Look for an outbox and set up the inventory API + // Initialize the Market Place or go update the outbox // - if (mOutboxId.isNull()) + if (LLMarketplaceInventoryImporter::getInstance()->getMarketPlaceStatus() == MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED) { - const bool do_not_create_folder = false; - const bool do_not_find_in_library = false; - - const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, do_not_create_folder, do_not_find_in_library); - - if (outbox_id.isNull()) - { - // Observe category creation to catch outbox creation - mCategoryAddedObserver = new LLOutboxAddedObserver(this); - gInventory.addObserver(mCategoryAddedObserver); - } - else - { - setupOutbox(outbox_id); - } + initializeMarketPlace(); + } + else + { + setupOutbox(); } + // + // Update the floater view + // updateView(); // // Trigger fetch of outbox contents // - fetchOutboxContents(); } @@ -223,13 +219,22 @@ void LLFloaterOutbox::fetchOutboxContents() } } -void LLFloaterOutbox::setupOutbox(const LLUUID& outboxId) +void LLFloaterOutbox::setupOutbox() { - llassert(outboxId.notNull()); - llassert(mOutboxId.isNull()); - llassert(mCategoriesObserver == NULL); + if (LLMarketplaceInventoryImporter::getInstance()->getMarketPlaceStatus() != MarketplaceStatusCodes::MARKET_PLACE_MERCHANT) + { + // If we are *not* a merchant or we have no market place connection established yet, do nothing + return; + } - mOutboxId = outboxId; + // We are a merchant. Get the outbox, create it if needs be. + mOutboxId = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, true, false); + if (mOutboxId.isNull()) + { + // We should never get there unles inventory fails badly + llerrs << "Inventory problem: failure to create the outbox for a merchant!" << llendl; + return; + } // No longer need to observe new category creation if (mCategoryAddedObserver && gInventory.containsObserver(mCategoryAddedObserver)) @@ -238,14 +243,19 @@ void LLFloaterOutbox::setupOutbox(const LLUUID& outboxId) delete mCategoryAddedObserver; mCategoryAddedObserver = NULL; } + llassert(!mCategoryAddedObserver); // Create observer for outbox modifications - mCategoriesObserver = new LLInventoryCategoriesObserver(); - gInventory.addObserver(mCategoriesObserver); + if (mCategoriesObserver == NULL) + { + mCategoriesObserver = new LLInventoryCategoriesObserver(); + gInventory.addObserver(mCategoriesObserver); + mCategoriesObserver->addCategory(mOutboxId, boost::bind(&LLFloaterOutbox::onOutboxChanged, this)); + } + llassert(mCategoriesObserver); - mCategoriesObserver->addCategory(mOutboxId, boost::bind(&LLFloaterOutbox::onOutboxChanged, this)); - - llassert(mOutboxInventoryPanel); + // Set up the outbox inventory view + // Singu Note: we handle this in postBuild, grabbing the panel from the built xml. // Reshape the inventory to the proper size LLRect inventory_placeholder_rect = mInventoryPlaceholder->getRect(); @@ -255,8 +265,12 @@ void LLFloaterOutbox::setupOutbox(const LLUUID& outboxId) mOutboxInventoryPanel->setSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME); mOutboxInventoryPanel->getFilter()->markDefault(); + // Get the content of the outbox fetchOutboxContents(); +} +void LLFloaterOutbox::initializeMarketPlace() +{ // // Initialize the marketplace import API // @@ -330,6 +344,7 @@ void LLFloaterOutbox::updateView() { mOutboxInventoryPanel->setVisible(TRUE); mInventoryPlaceholder->setVisible(FALSE); + mOutboxTopLevelDropZone->setVisible(TRUE); } else { @@ -338,13 +353,18 @@ void LLFloaterOutbox::updateView() mOutboxInventoryPanel->setVisible(FALSE); } + // Show the drop zone if there is an outbox folder + mOutboxTopLevelDropZone->setVisible(mOutboxId.notNull()); + mInventoryPlaceholder->setVisible(TRUE); std::string outbox_text; + std::string outbox_text2; std::string outbox_title; std::string outbox_tooltip; const LLSD& subs = getMarketplaceStringSubstitutions(); + U32 mkt_status = LLMarketplaceInventoryImporter::getInstance()->getMarketPlaceStatus(); // Text styles for marketplace hyperlinks std::string subs_link; @@ -352,28 +372,54 @@ void LLFloaterOutbox::updateView() if (mOutboxId.notNull()) { + // "Outbox is empty!" message strings outbox_text = LLTrans::getString("InventoryOutboxNoItems"); subs_link = "[MARKETPLACE_DASHBOARD_URL]"; subs_text = " " + LLTrans::getString("InventoryOutboxNoItemsSubs"); + outbox_text2 = LLTrans::getString("InventoryOutboxNoItems2"); outbox_title = LLTrans::getString("InventoryOutboxNoItemsTitle"); outbox_tooltip = LLTrans::getString("InventoryOutboxNoItemsTooltip"); } - else + else if (mkt_status <= MarketplaceStatusCodes::MARKET_PLACE_INITIALIZING) { + // "Initializing!" message strings + outbox_text = LLTrans::getString("InventoryOutboxInitializing"); + subs_link = "[MARKETPLACE_CREATE_STORE_URL]"; + subs_text = " " + LLTrans::getString("InventoryOutboxInitializingSubs"); + outbox_text2 = LLTrans::getString("InventoryOutboxInitializing2"); + outbox_title = LLTrans::getString("InventoryOutboxInitializingTitle"); + outbox_tooltip = LLTrans::getString("InventoryOutboxInitializingTooltip"); + } + else if (mkt_status == MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT) + { + // "Not a merchant!" message strings outbox_text = LLTrans::getString("InventoryOutboxNotMerchant"); subs_link = "[MARKETPLACE_CREATE_STORE_URL]"; subs_text = " " + LLTrans::getString("InventoryOutboxNotMerchantSubs"); + outbox_text2 = LLTrans::getString("InventoryOutboxNotMerchant2"); outbox_title = LLTrans::getString("InventoryOutboxNotMerchantTitle"); outbox_tooltip = LLTrans::getString("InventoryOutboxNotMerchantTooltip"); } + else + { + // "Errors!" message strings + outbox_text = LLTrans::getString("InventoryOutboxError"); + subs_link = "[MARKETPLACE_CREATE_STORE_URL]"; + subs_text = " " + LLTrans::getString("InventoryOutboxErrorSubs"); + outbox_text2 = " " + LLTrans::getString("InventoryOutboxError2"); + outbox_title = LLTrans::getString("InventoryOutboxErrorTitle"); + outbox_tooltip = LLTrans::getString("InventoryOutboxErrorTooltip"); + } mInventoryText->clear(); - mInventoryText->appendColoredText(outbox_text, false, false, gColors.getColor("TextFgReadOnlyColor")); + const LLColor4 color = gColors.getColor("TextFgReadOnlyColor"); + mInventoryText->appendColoredText(outbox_text, false, false, color); LLStringUtil::format(subs_link, subs); LLStyleSP subs_link_style(new LLStyle); subs_link_style->setLinkHREF(subs_link); subs_link_style->setColor(gSavedSettings.getColor4("HTMLLinkColor")); mInventoryText->appendStyledText(subs_text, false, false, subs_link_style); + mInventoryText->appendColoredText(outbox_text2, false, false, color); mInventoryTitle->setValue(outbox_title); mInventoryPlaceholder->getParent()->setToolTip(outbox_tooltip); } @@ -498,6 +544,11 @@ void LLFloaterOutbox::importReportResults(U32 status, const LLSD& content) void LLFloaterOutbox::importStatusChanged(bool inProgress) { + if (mOutboxId.isNull() && (LLMarketplaceInventoryImporter::getInstance()->getMarketPlaceStatus() == MarketplaceStatusCodes::MARKET_PLACE_MERCHANT)) + { + setupOutbox(); + } + if (inProgress) { if (mImportBusy) @@ -515,6 +566,7 @@ void LLFloaterOutbox::importStatusChanged(bool inProgress) } else { + setStatusString(""); mImportBusy = false; mImportButton->setEnabled(mOutboxItemCount > 0); mInventoryImportInProgress->setVisible(false); @@ -525,7 +577,7 @@ void LLFloaterOutbox::importStatusChanged(bool inProgress) void LLFloaterOutbox::initializationReportError(U32 status, const LLSD& content) { - if (status != MarketplaceErrorCodes::IMPORT_DONE) + if (status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST) { char status_string[16]; sprintf(status_string, "%d", status); diff --git a/indra/newview/llfloateroutbox.h b/indra/newview/llfloateroutbox.h index 92f301416..9f9222cb6 100644 --- a/indra/newview/llfloateroutbox.h +++ b/indra/newview/llfloateroutbox.h @@ -55,7 +55,7 @@ public: LLFloaterOutbox(const LLSD& key); ~LLFloaterOutbox(); - void setupOutbox(const LLUUID& outboxId); + void initializeMarketPlace(); // virtuals BOOL postBuild(); @@ -71,6 +71,7 @@ public: // void onMouseLeave(S32 x, S32 y, MASK mask); protected: + void setupOutbox(); void fetchOutboxContents(); void importReportResults(U32 status, const LLSD& content); diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index 7db143bc2..ed7c774c8 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -166,20 +166,25 @@ namespace LLMarketplaceImport llinfos << " SLM POST status: " << status << llendl; llinfos << " SLM POST reason: " << reason << llendl; llinfos << " SLM POST content: " << content.asString() << llendl; - llinfos << " SLM POST timer: " << slmPostTimer.getElapsedTimeF32() << llendl; } - if ((status == MarketplaceErrorCodes::IMPORT_REDIRECT) || - (status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) || - (status == MarketplaceErrorCodes::IMPORT_JOB_LOW_SPEED) || - (status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT)) + // MAINT-2301 : we determined we can safely ignore that error in that context + if (status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT) { if (gSavedSettings.getBOOL("InventoryOutboxLogging")) { - llinfos << " SLM POST clearing marketplace cookie due to authentication failure or timeout" << llendl; + llinfos << " SLM POST : Ignoring time out status and treating it as success" << llendl; } + status = MarketplaceErrorCodes::IMPORT_DONE; + } + if (status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST) + { + if (gSavedSettings.getBOOL("InventoryOutboxLogging")) + { + llinfos << " SLM POST clearing marketplace cookie due to client or server error" << llendl; + } sMarketplaceCookie.clear(); } @@ -224,21 +229,23 @@ namespace LLMarketplaceImport llinfos << " SLM GET status: " << status << llendl; llinfos << " SLM GET reason: " << reason << llendl; llinfos << " SLM GET content: " << content.asString() << llendl; - llinfos << " SLM GET timer: " << slmGetTimer.getElapsedTimeF32() << llendl; } - if ((status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) || - (status == MarketplaceErrorCodes::IMPORT_JOB_LOW_SPEED) || - (status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT)) + // MAINT-2452 : Do not clear the cookie on IMPORT_DONE_WITH_ERRORS + if ((status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST) && + (status != MarketplaceErrorCodes::IMPORT_DONE_WITH_ERRORS)) { if (gSavedSettings.getBOOL("InventoryOutboxLogging")) { - llinfos << " SLM GET clearing marketplace cookie due to authentication failure or timeout (" << status << " / " << reason << ")." << llendl; + llinfos << " SLM GET clearing marketplace cookie due to client or server error (" << status << " / " << reason << ")." << llendl; } - sMarketplaceCookie.clear(); } + else if (gSavedSettings.getBOOL("InventoryOutboxLogging") && (status == MarketplaceErrorCodes::IMPORT_DONE_WITH_ERRORS)) + { + llinfos << " SLM GET : Got IMPORT_DONE_WITH_ERRORS, marketplace cookie not cleared." << llendl; + } sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_PROCESSING); sImportGetPending = false; @@ -334,7 +341,9 @@ namespace LLMarketplaceImport if (gSavedSettings.getBOOL("InventoryOutboxLogging")) { - llinfos << " SLM GET: " << url << llendl; + llinfos << " SLM GET: pollStatus, LLHTTPClient::get, url = " << url << llendl; + llinfos << " SLM GET: headers " << llendl; + llinfos << headers << llendl; } slmGetTimer.start(); @@ -368,7 +377,9 @@ namespace LLMarketplaceImport if (gSavedSettings.getBOOL("InventoryOutboxLogging")) { - llinfos << " SLM POST: " << url << llendl; + llinfos << " SLM POST: triggerImport, LLHTTPClient::post, url = " << url << llendl; + llinfos << " SLM POST: headers " << llendl; + llinfos << headers << llendl; } slmPostTimer.start(); @@ -404,6 +415,7 @@ LLMarketplaceInventoryImporter::LLMarketplaceInventoryImporter() : mAutoTriggerImport(false) , mImportInProgress(false) , mInitialized(false) + , mMarketPlaceStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED) , mErrorInitSignal(NULL) , mStatusChangedSignal(NULL) , mStatusReportSignal(NULL) @@ -446,16 +458,20 @@ void LLMarketplaceInventoryImporter::initialize() if (!LLMarketplaceImport::hasSessionCookie()) { + mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_INITIALIZING; LLMarketplaceImport::establishMarketplaceSessionCookie(); } + else + { + mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_MERCHANT; + } } void LLMarketplaceInventoryImporter::reinitializeAndTriggerImport() { mInitialized = false; - + mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED; initialize(); - mAutoTriggerImport = true; } @@ -507,17 +523,30 @@ void LLMarketplaceInventoryImporter::updateImport() if (mInitialized) { + mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_MERCHANT; // Follow up with auto trigger of import if (mAutoTriggerImport) { mAutoTriggerImport = false; - mImportInProgress = triggerImport(); } } - else if (mErrorInitSignal) + else { - (*mErrorInitSignal)(LLMarketplaceImport::getResultStatus(), LLMarketplaceImport::getResults()); + U32 status = LLMarketplaceImport::getResultStatus(); + if ((status == MarketplaceErrorCodes::IMPORT_FORBIDDEN) || + (status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR)) + { + mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT; + } + else + { + mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE; + } + if (mErrorInitSignal && (mMarketPlaceStatus == MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE)) + { + (*mErrorInitSignal)(LLMarketplaceImport::getResultStatus(), LLMarketplaceImport::getResults()); + } } } } diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h index af7c864c0..4e9e6ee81 100644 --- a/indra/newview/llmarketplacefunctions.h +++ b/indra/newview/llmarketplacefunctions.h @@ -48,11 +48,28 @@ namespace MarketplaceErrorCodes IMPORT_DONE = HTTP_OK, IMPORT_PROCESSING = HTTP_ACCEPTED, IMPORT_REDIRECT = HTTP_FOUND, + IMPORT_BAD_REQUEST = HTTP_BAD_REQUEST, IMPORT_AUTHENTICATION_ERROR = HTTP_UNAUTHORIZED, + IMPORT_FORBIDDEN = HTTP_FORBIDDEN, + IMPORT_NOT_FOUND = HTTP_NOT_FOUND, IMPORT_DONE_WITH_ERRORS = HTTP_CONFLICT, IMPORT_JOB_FAILED = HTTP_GONE, IMPORT_JOB_LOW_SPEED = HTTP_INTERNAL_ERROR_LOW_SPEED, - IMPORT_JOB_TIMEOUT = HTTP_INTERNAL_ERROR_CURL_TIMEOUT + IMPORT_JOB_TIMEOUT = HTTP_INTERNAL_ERROR_CURL_TIMEOUT, + IMPORT_SERVER_SITE_DOWN = HTTP_INTERNAL_SERVER_ERROR, + IMPORT_SERVER_API_DISABLED = HTTP_SERVICE_UNAVAILABLE, + }; +} + +namespace MarketplaceStatusCodes +{ + enum sCode + { + MARKET_PLACE_NOT_INITIALIZED = 0, + MARKET_PLACE_INITIALIZING = 1, + MARKET_PLACE_CONNECTION_FAILURE = 2, + MARKET_PLACE_MERCHANT = 3, + MARKET_PLACE_NOT_MERCHANT = 4, }; } @@ -75,6 +92,7 @@ public: void initialize(); bool triggerImport(); bool isImportInProgress() const { return mImportInProgress; } + U32 getMarketPlaceStatus() const { return mMarketPlaceStatus; } protected: void reinitializeAndTriggerImport(); @@ -84,6 +102,7 @@ private: bool mAutoTriggerImport; bool mImportInProgress; bool mInitialized; + U32 mMarketPlaceStatus; status_report_signal_t * mErrorInitSignal; status_changed_signal_t * mStatusChangedSignal; diff --git a/indra/newview/skins/default/xui/en-us/notifications.xml b/indra/newview/skins/default/xui/en-us/notifications.xml index a9062a821..58f8eadb1 100644 --- a/indra/newview/skins/default/xui/en-us/notifications.xml +++ b/indra/newview/skins/default/xui/en-us/notifications.xml @@ -370,7 +370,7 @@ See the [[MARKETPLACE_IMPORTS_URL] error log] for more information. icon="alertmodal.tga" name="OutboxImportFailed" type="alertmodal"> -Transfer failed +Transfer failed with error '[ERROR_CODE]' No folders were sent to the Marketplace because of a system or network error. Try again later. @@ -383,7 +383,7 @@ No folders were sent to the Marketplace because of a system or network error. T icon="alertmodal.tga" name="OutboxInitFailed" type="alertmodal"> -Marketplace initialization failed +Marketplace initialization failed with error '[ERROR_CODE]' Initialization with the Marketplace failed because of a system or network error. Try again later. diff --git a/indra/newview/skins/default/xui/en-us/strings.xml b/indra/newview/skins/default/xui/en-us/strings.xml index 48c9a6657..c81dab602 100644 --- a/indra/newview/skins/default/xui/en-us/strings.xml +++ b/indra/newview/skins/default/xui/en-us/strings.xml @@ -3009,13 +3009,29 @@ Where tag = tag string to match. Removes bot's matching the tag. If you'd like to become a merchant, you'll need to - create a Marketplace store. + create a Marketplace store + . Your outbox is empty. Drag folders to this area and click "Send to Marketplace" to list them for sale on the - Marketplace. + Marketplace + . + Initializing Marketplace. + + +We are accessing your account on the + + Marketplace store + . + Marketplace Errors. + + +The + + Marketplace store + is returning errors.