diff --git a/indra/newview/fsfloaterprimfeed.cpp b/indra/newview/fsfloaterprimfeed.cpp index c665d09198..15ca7514e1 100644 --- a/indra/newview/fsfloaterprimfeed.cpp +++ b/indra/newview/fsfloaterprimfeed.cpp @@ -74,6 +74,7 @@ FSPrimfeedPhotoPanel::FSPrimfeedPhotoPanel() : mDescriptionTextBox(nullptr), mLocationCheckbox(nullptr), mRatingComboBox(nullptr), + mStoresComboBox(nullptr), mPostButton(nullptr), mBtnPreview(nullptr), mBigPreviewFloater(nullptr) @@ -88,6 +89,16 @@ FSPrimfeedPhotoPanel::FSPrimfeedPhotoPanel() : LL_DEBUGS("primfeed") << "Info button clicked, opening " << url << LL_ENDL; LLWeb::loadURLExternal(url); }); + FSPrimfeedAuth::sPrimfeedAuthPump->listen("FSPrimfeedPhotoPanel", + [this](const LLSD& data) + { + if ( data["responseType"].asString() == "primfeed_user_info" ) + { + this->loadPrimfeedInfo(data); + return true; + } + return false; + }); } FSPrimfeedPhotoPanel::~FSPrimfeedPhotoPanel() @@ -97,8 +108,6 @@ FSPrimfeedPhotoPanel::~FSPrimfeedPhotoPanel() mPreviewHandle.get()->die(); } - FSPrimfeedAuth::sPrimfeedAuthPump->stopListening("FSPrimfeedAccountPanel"); - gSavedSettings.setS32("FSLastSnapshotToPrimfeedResolution", getChild("resolution_combobox")->getCurrentIndex()); gSavedSettings.setS32("FSLastSnapshotToPrimfeedWidth", getChild("custom_snapshot_width")->getValue().asInteger()); gSavedSettings.setS32("FSLastSnapshotToPrimfeedHeight", getChild("custom_snapshot_height")->getValue().asInteger()); @@ -121,6 +130,7 @@ bool FSPrimfeedPhotoPanel::postBuild() mCommercialCheckbox = getChild("primfeed_commercial_content"); mPublicGalleryCheckbox = getChild("primfeed_add_to_public_gallery"); mRatingComboBox = getChild("rating_combobox"); + mStoresComboBox = getChild("stores_combobox"); mPostButton = getChild("post_photo_btn"); mCancelButton = getChild("cancel_photo_btn"); mBigPreviewFloater = dynamic_cast(LLFloaterReg::getInstance("big_preview")); @@ -192,6 +202,8 @@ void FSPrimfeedPhotoPanel::draw() mCancelButton->setEnabled(can_post); mDescriptionTextBox->setEnabled(can_post); mRatingComboBox->setEnabled(can_post); + // If the stores combo box is present, enable it only if we have stores to select from + mStoresComboBox->setEnabled(can_post && ((LLComboBox*)mStoresComboBox)->getItemCount() > 1); mResolutionComboBox->setEnabled(can_post); mFilterComboBox->setEnabled(can_post); mRefreshBtn->setEnabled(can_post); @@ -327,7 +339,7 @@ bool FSPrimfeedPhotoPanel::onPrimfeedConnectStateChange(const LLSD& /*data*/) { if (FSPrimfeedAuth::isAuthorized()) { - sendPhoto(); + return true; } return false; @@ -355,7 +367,7 @@ void FSPrimfeedPhotoPanel::sendPhoto() int content_rating = mRatingComboBox->getValue().asInteger(); bool post_to_public_gallery = mPublicGalleryCheckbox->getValue().asBoolean(); bool commercial_content = mCommercialCheckbox->getValue().asBoolean(); - + std::string store_id = mStoresComboBox->getValue().asString(); // Get the image LLSnapshotLivePreview* previewp = getPreviewView(); @@ -376,6 +388,11 @@ void FSPrimfeedPhotoPanel::sendPhoto() params["location"] = slurl_string; } + if (!store_id.empty()) + { + // Add the store ID if we have one selected + params["store_id"] = store_id; + } FSPrimfeedConnect::instance().uploadPhoto(params, previewp->getFormattedImage().get(), [this](bool success, const std::string& url) @@ -529,6 +546,34 @@ void FSPrimfeedPhotoPanel::checkAspectRatio(S32 index) } } +void FSPrimfeedPhotoPanel::loadPrimfeedInfo(LLSD const& data) +{ + if (!mStoresComboBox) return; + + // Clear any existing entries + mStoresComboBox->clearRows(); + mStoresComboBox->add(LLTrans::getString("Personal"), LLSD("")); + + // Read the saved stores array + LLSD stores = data["stores"]; + if (!stores.isArray() || stores.size() == 0) + { + // No stores - disable the combobox + mStoresComboBox->setEnabled(FALSE); + return; + } + + mStoresComboBox->setEnabled(TRUE); + for (S32 i = 0; i < stores.size(); ++i) + { + LLSD const& store = stores[i]; + std::string id = store["id"].asString(); + std::string name = store["name"].asString(); + mStoresComboBox->add(name, LLSD(id)); + } + mStoresComboBox->setCurrentByIndex(0); +} + LLUICtrl* FSPrimfeedPhotoPanel::getRefreshBtn() { return mRefreshBtn; @@ -536,13 +581,10 @@ LLUICtrl* FSPrimfeedPhotoPanel::getRefreshBtn() void FSPrimfeedPhotoPanel::onOpen(const LLSD& key) { - if (!FSPrimfeedAuth::isAuthorized()) - { - // Reauthorise if necessary. - FSPrimfeedAuth::initiateAuthRequest(); - LLSD dummy; - onPrimfeedConnectStateChange(dummy); - } + // Reauthorise if necessary. + FSPrimfeedAuth::initiateAuthRequest(); + LLSD dummy; + onPrimfeedConnectStateChange(dummy); } void FSPrimfeedPhotoPanel::uploadCallback(bool success, const LLSD& response) @@ -621,6 +663,7 @@ bool FSPrimfeedPhotoPanel::checkImageSize(LLSnapshotLivePreview* previewp, S32& return (w != width || h != height); } + /////////////////////////// // FSPrimfeedAccountPanel/// /////////////////////////// @@ -639,10 +682,24 @@ FSPrimfeedAccountPanel::FSPrimfeedAccountPanel() : FSPrimfeedAuth::sPrimfeedAuthPump->listen("FSPrimfeedAccountPanel", [this](const LLSD& data) { - bool success = data["success"].asBoolean(); - primfeedAuthResponse(success, data); - return true; - }); + if ( data.has("responseType")) + { + auto response_type = data["responseType"].asString(); + if(response_type == "primfeed_auth_response") + { + bool success = data["success"].asBoolean(); + primfeedAuthResponse(success, data); + return true; + } + if(response_type == "primfeed_auth_reset") + { + bool success = data["success"].asBoolean(); + primfeedAuthResponse(success, data); + return true; + } + } + return false; + }); setVisibleCallback([this](LLUICtrl*, bool visible) { onVisibilityChange(visible); }); } @@ -782,6 +839,12 @@ void FSPrimfeedAccountPanel::onDisconnect() onPrimfeedConnectStateChange(dummy); } +FSPrimfeedAccountPanel::~FSPrimfeedAccountPanel() +{ + // Disconnect the primfeed auth pump + FSPrimfeedAuth::sPrimfeedAuthPump->stopListening("FSPrimfeedAccountPanel"); +} + //////////////////////// // FSFloaterPrimfeed///// //////////////////////// @@ -789,10 +852,10 @@ void FSPrimfeedAccountPanel::onDisconnect() FSFloaterPrimfeed::FSFloaterPrimfeed(const LLSD& key) : LLFloater(key), mPrimfeedPhotoPanel(nullptr), + mPrimfeedAccountPanel(nullptr), mStatusErrorText(nullptr), mStatusLoadingText(nullptr), - mStatusLoadingIndicator(nullptr), - mPrimfeedAccountPanel(nullptr) + mStatusLoadingIndicator(nullptr) { mCommitCallbackRegistrar.add("SocialSharing.Cancel", [this](LLUICtrl*, const LLSD&) { onCancel(); }); } diff --git a/indra/newview/fsfloaterprimfeed.h b/indra/newview/fsfloaterprimfeed.h index 312f06c130..5d94984574 100644 --- a/indra/newview/fsfloaterprimfeed.h +++ b/indra/newview/fsfloaterprimfeed.h @@ -34,6 +34,7 @@ class LLIconCtrl; class LLCheckBoxCtrl; +class LLComboBox; class LLSnapshotLivePreview; class LLFloaterBigPreview; @@ -52,6 +53,7 @@ public: bool postBuild() override; S32 notify(const LLSD& info); void draw() override; + void loadPrimfeedInfo(LLSD const& data); LLSnapshotLivePreview* getPreviewView(); void onVisibilityChange(bool new_visibility); @@ -94,6 +96,7 @@ private: LLUICtrl * mPostButton; LLUICtrl * mCancelButton; LLButton * mBtnPreview; + LLComboBox * mStoresComboBox; LLFloaterBigPreview * mBigPreviewFloater; }; @@ -102,6 +105,7 @@ class FSPrimfeedAccountPanel : public LLPanel { public: FSPrimfeedAccountPanel(); + ~FSPrimfeedAccountPanel(); bool postBuild() override; void draw() override; diff --git a/indra/newview/fsprimfeedauth.cpp b/indra/newview/fsprimfeedauth.cpp index 2c7c66f60c..20b9b6a042 100644 --- a/indra/newview/fsprimfeedauth.cpp +++ b/indra/newview/fsprimfeedauth.cpp @@ -112,31 +112,25 @@ void FSPrimfeedAuth::initiateAuthRequest() // It should be called when the user clicks the "Authenticate" button. // Also triggered on opening the floater. // The actual implementation is in the create() method. - - if (!isAuthorized()) + + if (sPrimfeedAuth) { - if (sPrimfeedAuth) + LLNotificationsUtil::add("PrimfeedAuthorizationAlreadyInProgress"); + return; + } + // If no token stored, begin the login request; otherwise check user status. + sPrimfeedAuth = FSPrimfeedAuth::create( + [](bool success, const LLSD &response) { - LLNotificationsUtil::add("PrimfeedAuthorizationAlreadyInProgress"); - return; + LLSD event_data = response; + event_data["responseType"] = "primfeed_auth_response"; + event_data["success"] = success; + sPrimfeedAuthPump->post(event_data); + // Now that auth is complete, clear the static pointer. + sPrimfeedAuth.reset(); } - // If no token stored, begin the login request; otherwise check user status. - sPrimfeedAuth = FSPrimfeedAuth::create( - [](bool success, const LLSD &response) - { - LLSD event_data = response; - event_data["success"] = success; - sPrimfeedAuthPump->post(event_data); - // Now that auth is complete, clear the static pointer. - sPrimfeedAuth.reset(); - } - ); - FSPrimfeedConnect::instance().setConnectionState(FSPrimfeedConnect::PRIMFEED_CONNECTING); - } - else - { - LLNotificationsUtil::add("PrimfeedAlreadyAuthorized"); - } + ); + FSPrimfeedConnect::instance().setConnectionState(FSPrimfeedConnect::PRIMFEED_CONNECTING); } void FSPrimfeedAuth::resetAuthStatus() @@ -147,7 +141,7 @@ void FSPrimfeedAuth::resetAuthStatus() gSavedPerAccountSettings.setString("FSPrimfeedPlan", ""); gSavedPerAccountSettings.setString("FSPrimfeedUsername", ""); LLSD event_data; - event_data["status"] = "reset"; + event_data["responseType"] = "primfeed_auth_reset"; event_data["success"] = "false"; sPrimfeedAuthPump->post(event_data); FSPrimfeedConnect::instance().setConnectionState(FSPrimfeedConnect::PRIMFEED_DISCONNECTED); @@ -201,7 +195,8 @@ std::shared_ptr FSPrimfeedAuth::create(authorized_callback_t cal FSPrimfeedConnect::instance().setConnectionState(FSPrimfeedConnect::PRIMFEED_CONNECTING); // If no token stored, begin the login request; otherwise check user status. - if (gSavedPerAccountSettings.getString("FSPrimfeedOAuthToken").empty()) + auth->mOauthToken = gSavedPerAccountSettings.getString("FSPrimfeedOAuthToken"); + if (auth->mOauthToken.empty()) { auth->beginLoginRequest(); } @@ -432,22 +427,23 @@ void FSPrimfeedAuth::checkUserStatus() } -void FSPrimfeedAuth::gotUserStatus(bool success, const LLSD &response) +void FSPrimfeedAuth::gotUserStatus(bool success, const LLSD &response) const { LL_INFOS("Primfeed") << "User status: " << response << "(" << success << ")" << LL_ENDL; - if (success && response.has("plan")) + if (success && response.has("plan") && response.has("username") && response.has("link")) { gSavedPerAccountSettings.setString("FSPrimfeedOAuthToken", mOauthToken); gSavedPerAccountSettings.setString("FSPrimfeedPlan", response["plan"].asString()); gSavedPerAccountSettings.setString("FSPrimfeedProfileLink", response["link"].asString()); gSavedPerAccountSettings.setString("FSPrimfeedUsername", response["username"].asString()); FSPrimfeedConnect::instance().setConnectionState(FSPrimfeedConnect::PRIMFEED_CONNECTED); + LLSD event_data = response; + event_data["responseType"] = "primfeed_user_info"; + sPrimfeedAuthPump->post(event_data); mCallback(true, response); + return; } - else - { - LLNotificationsUtil::add("PrimfeedUserStatusFailed"); - FSPrimfeedConnect::instance().setConnectionState(FSPrimfeedConnect::PRIMFEED_DISCONNECTED); - mCallback(false, response); - } + LLNotificationsUtil::add("PrimfeedUserStatusFailed"); + FSPrimfeedConnect::instance().setConnectionState(FSPrimfeedConnect::PRIMFEED_DISCONNECTED); + mCallback(false, response); } diff --git a/indra/newview/fsprimfeedauth.h b/indra/newview/fsprimfeedauth.h index 43fc36a937..5e3934269f 100644 --- a/indra/newview/fsprimfeedauth.h +++ b/indra/newview/fsprimfeedauth.h @@ -79,7 +79,7 @@ private: // Callback when the validate response is received. void gotValidateResponse(bool success, const LLSD &response); // Callback when the user status response is received. - void gotUserStatus(bool success, const LLSD &response); + void gotUserStatus(bool success, const LLSD &response) const; boost::signals2::connection mInstantMessageConnection; boost::signals2::connection mChatMessageConnection; diff --git a/indra/newview/fsprimfeedconnect.cpp b/indra/newview/fsprimfeedconnect.cpp index 6c6d849152..442a4789e5 100644 --- a/indra/newview/fsprimfeedconnect.cpp +++ b/indra/newview/fsprimfeedconnect.cpp @@ -89,6 +89,7 @@ void FSPrimfeedConnect::uploadPhotoCoro(const LLSD& params, LLImageFormatted* im addPart("location", params["location"].asString()); } + LL_DEBUGS("primfeed") << "Adding image file header" << LL_ENDL; body << dash << sep << "Content-Disposition: form-data; name=\"image\"; filename=\"snapshot." << fmt << "\"" << sep @@ -122,12 +123,11 @@ void FSPrimfeedConnect::uploadPhotoCoro(const LLSD& params, LLImageFormatted* im headers->append(HTTP_OUT_HEADER_USER_AGENT, FS_PF_USER_AGENT); headers->append("Authorization", "Bearer " + token); headers->append("pf-viewer-api-key", apiKey); - headers->append("Content-Type", "multipart/form-data; boundary=" + boundary); - LL_DEBUGS("primfeed") << "Dumping HTTP headers for POST:" << LL_ENDL; - for (auto it = headers->begin(); it != headers->end(); ++it) + if (params.has("store_id") && !params["store_id"].asString().empty()) { - LL_DEBUGS("primfeed") << it->first << ": " << it->second << LL_ENDL; + headers->append("kynno-selected-store", params["store_id"].asString()); } + headers->append("Content-Type", "multipart/form-data; boundary=" + boundary); LL_DEBUGS("primfeed") << "Headers set" << LL_ENDL; LL_DEBUGS("primfeed") << "Starting HTTP POST" << LL_ENDL; @@ -182,9 +182,3 @@ bool FSPrimfeedConnect::isTransactionOngoing() const mConnectionState == PRIMFEED_DISCONNECTING); } -void FSPrimfeedConnect::loadPrimfeedInfo() -{ - LL_DEBUGS("primfeed") << "loadPrimfeedInfo() called" << LL_ENDL; - // Nothing to do here for Primfeed - setConnectionState(PRIMFEED_CONNECTED); -} \ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/floater_primfeed.xml b/indra/newview/skins/default/xui/en/floater_primfeed.xml index 6b03fee976..c75d48bc59 100644 --- a/indra/newview/skins/default/xui/en/floater_primfeed.xml +++ b/indra/newview/skins/default/xui/en/floater_primfeed.xml @@ -10,10 +10,10 @@ single_instance="true" reuse_instance="true" title="Share to Primfeed" - height="600" + height="630" width="272"> + + Post as: + + + +