From 2dc46964b4894474591e0b2bc7c075fcf1476af6 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Thu, 8 Feb 2018 01:26:09 -0600 Subject: [PATCH] Simple update check mechanism, and tons of notification tweaking to make the notifications look less crap. --- indra/llmessage/aihttptimeoutpolicy.cpp | 1 + indra/llui/llalertdialog.cpp | 16 ++ indra/llui/llcheckboxctrl.h | 6 +- indra/llui/lldraghandle.cpp | 7 + indra/llui/lldraghandle.h | 2 + indra/llui/llnotifications.cpp | 2 +- indra/newview/CMakeLists.txt | 2 + .../newview/app_settings/settings_ascent.xml | 55 ++++++ indra/newview/llnotify.cpp | 42 +++++ indra/newview/llstartup.cpp | 2 + indra/newview/shupdatechecker.cpp | 171 ++++++++++++++++++ .../skins/default/xui/en-us/notifications.xml | 86 +++++++-- 12 files changed, 375 insertions(+), 17 deletions(-) create mode 100644 indra/newview/shupdatechecker.cpp diff --git a/indra/llmessage/aihttptimeoutpolicy.cpp b/indra/llmessage/aihttptimeoutpolicy.cpp index ca3b24a76..bbe1d9e6a 100644 --- a/indra/llmessage/aihttptimeoutpolicy.cpp +++ b/indra/llmessage/aihttptimeoutpolicy.cpp @@ -962,3 +962,4 @@ P(wholeModelFeeResponder); P(wholeModelUploadResponder); P2(XMLRPCResponder, connect_40s); P2(crashLoggerResponder, transfer_300s); +P(getUpdateInfoResponder); \ No newline at end of file diff --git a/indra/llui/llalertdialog.cpp b/indra/llui/llalertdialog.cpp index 3b4931341..b7cef0a2e 100644 --- a/indra/llui/llalertdialog.cpp +++ b/indra/llui/llalertdialog.cpp @@ -48,6 +48,7 @@ #include "lluictrlfactory.h" #include "llnotifications.h" #include "llfunctorregistry.h" +#include "lldraghandle.h" const S32 MAX_ALLOWED_MSG_WIDTH = 400; const F32 DEFAULT_BUTTON_DELAY = 0.5f; @@ -233,6 +234,12 @@ LLAlertDialog::LLAlertDialog( LLNotificationPtr notification, bool modal) msg_box->setColor( LLUI::sColorsGroup->getColor( "AlertTextColor" ) ); } + LLDragHandle* handle = getDragHandle(); + if (handle) + { + getDragHandle()->setTextColor(LLUI::sColorsGroup->getColor(mCaution ? "AlertCautionTextColor" : "AlertTextColor")); + } + LLRect rect; rect.setLeftTopAndSize( msg_x, msg_y, text_rect.getWidth(), text_rect.getHeight() ); msg_box->setRect( rect ); @@ -257,6 +264,10 @@ LLAlertDialog::LLAlertDialog( LLNotificationPtr notification, bool modal) button_data.mText); btn->setClickedCallback(boost::bind(&LLAlertDialog::onButtonPressed, this, _1, button_data.mUrl)); + if (mCaution) + { + btn->setColor(LLUI::sColorsGroup->getColor("ButtonCautionImageColor")); + } addChild(btn); @@ -370,6 +381,11 @@ bool LLAlertDialog::setCheckBox( const std::string& check_title, const std::stri max_msg_width, LINE_HEIGHT); mCheck = new LLCheckboxCtrl(std::string("check"), check_rect, check_title, font, boost::bind(&LLAlertDialog::onClickIgnore, this, _1)); + mCheck->setEnabledColor(LLUI::sColorsGroup->getColor( mCaution ? "AlertCautionTextColor" : "AlertTextColor")); + if (mCaution) + { + mCheck->setButtonColor(LLUI::sColorsGroup->getColor("ButtonCautionImageColor")); + } addChild(mCheck); return true; diff --git a/indra/llui/llcheckboxctrl.h b/indra/llui/llcheckboxctrl.h index 47eb46670..c0fdf842d 100644 --- a/indra/llui/llcheckboxctrl.h +++ b/indra/llui/llcheckboxctrl.h @@ -100,8 +100,10 @@ public: // LLCheckBoxCtrl interface virtual BOOL toggle() { return mButton->toggleState(); } // returns new state - void setEnabledColor( const LLColor4 &color ) { mTextEnabledColor = color; } - void setDisabledColor( const LLColor4 &color ) { mTextDisabledColor = color; } + void setEnabledColor(const LLColor4 &color) { mTextEnabledColor = color; setEnabled(getEnabled()); } + void setDisabledColor( const LLColor4 &color ) { mTextDisabledColor = color; setEnabled(getEnabled()); } + + void setButtonColor(const LLColor4 &color) { if (mButton) mButton->setColor(color); } void setLabel( const LLStringExplicit& label ); std::string getLabel() const; diff --git a/indra/llui/lldraghandle.cpp b/indra/llui/lldraghandle.cpp index 929548137..741f1c694 100644 --- a/indra/llui/lldraghandle.cpp +++ b/indra/llui/lldraghandle.cpp @@ -301,6 +301,13 @@ BOOL LLDragHandle::handleMouseUp(S32 x, S32 y, MASK mask) return TRUE; } +void LLDragHandle::setTextColor(const LLColor4& color) +{ + if (mTitleBox) + { + mTitleBox->setColor(color); + } +} BOOL LLDragHandle::handleHover(S32 x, S32 y, MASK mask) { diff --git a/indra/llui/lldraghandle.h b/indra/llui/lldraghandle.h index 9eb3e55a6..a573d458d 100644 --- a/indra/llui/lldraghandle.h +++ b/indra/llui/lldraghandle.h @@ -63,6 +63,8 @@ public: virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); + virtual void setTextColor(const LLColor4& color); + protected: LLTextBox* getTitleBox() const { return mTitleBox; } void setTitleBox(LLTextBox*); diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 990416c9a..5c9dfb74a 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -891,7 +891,7 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt assert(!wasFound); if (passesFilter) { - LL_INFOS() << "Inserting " << pNotification->getName() << LL_ENDL; + //LL_INFOS() << "Inserting " << pNotification->getName() << LL_ENDL; // not in our list, add it and say so mItems.insert(pNotification); abortProcessing = mChanged(payload); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 1b28fcdca..1374f9835 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -594,6 +594,7 @@ set(viewer_SOURCE_FILES scriptcounter.cpp sgmemstat.cpp shcommandhandler.cpp + shupdatechecker.cpp shfloatermediaticker.cpp wlfPanel_AdvSettings.cpp ) @@ -1136,6 +1137,7 @@ set(viewer_HEADER_FILES sgmemstat.h shcommandhandler.h shfloatermediaticker.h + shupdatechecker.h wlfPanel_AdvSettings.h ) diff --git a/indra/newview/app_settings/settings_ascent.xml b/indra/newview/app_settings/settings_ascent.xml index 94faa90f6..dd373885d 100644 --- a/indra/newview/app_settings/settings_ascent.xml +++ b/indra/newview/app_settings/settings_ascent.xml @@ -873,6 +873,61 @@ Value 1 + SinguLastKnownReleaseBuild + + Comment + Latest known available verson. + Persist + 1 + Type + S32 + Value + 0 + + SinguLastKnownAlphaBuild + + Comment + Latest known available verson. + Persist + 1 + Type + S32 + Value + 0 + + WarnRecommendedUpdate + + Comment + Enables recommended update notification dialog + Persist + 1 + Type + Boolean + Value + 1 + + WarnUrgentUpdate + + Comment + Enables critical update notification dialog + Persist + 1 + Type + Boolean + Value + 1 + + WarnUrgentUpdateModal + + Comment + Enables critical update modal dialog + Persist + 1 + Type + Boolean + Value + 1 + UseWebProfiles Comment diff --git a/indra/newview/llnotify.cpp b/indra/newview/llnotify.cpp index 2bba6d4f9..d60d53275 100644 --- a/indra/newview/llnotify.cpp +++ b/indra/newview/llnotify.cpp @@ -54,6 +54,7 @@ #include "llfloaterchat.h" // for add_chat_history() #include "lloverlaybar.h" // for gOverlayBar #include "lluictrlfactory.h" +#include "llcheckboxctrl.h" #include "hippogridmanager.h" @@ -183,6 +184,8 @@ LLNotifyBox::LLNotifyBox(LLNotificationPtr notification) bool layout_script_dialog(notification->getName() == "ScriptDialog" || notification->getName() == "ScriptDialogGroup"); LLRect rect = mIsTip ? getNotifyTipRect(message) : getNotifyRect(is_textbox ? 10 : mNumOptions, layout_script_dialog, mIsCaution); + if ((form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE || form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE)) + rect.mBottom -= BTN_HEIGHT; setRect(rect); setFollows(mIsTip ? (FOLLOWS_BOTTOM|FOLLOWS_RIGHT) : (FOLLOWS_TOP|FOLLOWS_RIGHT)); setBackgroundVisible(FALSE); @@ -359,6 +362,45 @@ LLNotifyBox::LLNotifyBox(LLNotificationPtr notification) addButton("OK", "OK", false, true, layout_script_dialog); mAddedDefaultBtn = true; } + + std::string check_title; + if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE) + { + check_title = LLNotificationTemplates::instance().getGlobalString("skipnexttime"); + } + else if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE) + { + check_title = LLNotificationTemplates::instance().getGlobalString("alwayschoose"); + } + if (!check_title.empty()) + { + const LLFontGL* font = LLResMgr::getInstance()->getRes(LLFONT_SANSSERIF); + S32 line_height = llfloor(font->getLineHeight() + 0.99f); + + // Extend dialog for "check next time" + S32 max_msg_width = getRect().getWidth() - HPAD * 9; + S32 check_width = S32(font->getWidth(check_title) + 0.99f) + 16; + max_msg_width = llmax(max_msg_width, check_width); + + S32 msg_x = (getRect().getWidth() - max_msg_width) / 2; + + LLRect check_rect; + check_rect.setOriginAndSize(msg_x, BOTTOM_PAD + BTN_HEIGHT + VPAD*2 + (BTN_HEIGHT + VPAD) * (mNumButtons / 3), + max_msg_width, line_height); + + LLCheckboxCtrl* check = new LLCheckboxCtrl(std::string("check"), check_rect, check_title, font, + // Lambda abuse. + [this](LLUICtrl* ctrl, const LLSD& param) + { + this->mNotification->setIgnored(ctrl->getValue()); + }); + check->setEnabledColor(LLUI::sColorsGroup->getColor(mIsCaution ? "AlertCautionTextColor" : "AlertTextColor")); + if (mIsCaution) + { + check->setButtonColor(LLUI::sColorsGroup->getColor("ButtonCautionImageColor")); + } + addChild(check); + } if (++sNotifyBoxCount <= 0) LL_WARNS() << "A notification was mishandled. sNotifyBoxCount = " << sNotifyBoxCount << LL_ENDL; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 4a6463bfd..ea17267b9 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -225,6 +225,7 @@ #include "llfloaterblacklist.h" #include "scriptcounter.h" #include "shfloatermediaticker.h" +#include "shupdatechecker.h" #include "llpacketring.h" // @@ -849,6 +850,7 @@ bool idle_startup() // Go to the next startup state LLStartUp::setStartupState( STATE_BROWSER_INIT ); + check_for_updates(); return FALSE; } diff --git a/indra/newview/shupdatechecker.cpp b/indra/newview/shupdatechecker.cpp new file mode 100644 index 000000000..997ac6b44 --- /dev/null +++ b/indra/newview/shupdatechecker.cpp @@ -0,0 +1,171 @@ +#include "llviewerprecompiledheaders.h" + +#include "llviewerwindow.h" +#include "llwindow.h" +#include "llpanelgeneral.h" +#include "llappviewer.h" +#include "llbutton.h" +#include "llviewercontrol.h" +#include "llnotificationsutil.h" +#include "llstartup.h" +#include "llviewerwindow.h" // to link into child list +#include "llnotify.h" +#include "lluictrlfactory.h" +#include "llhttpclient.h" +#include "llversioninfo.h" +#include "llbufferstream.h" +#include "llweb.h" + + +#include + +extern AIHTTPTimeoutPolicy getUpdateInfoResponder_timeout; +/////////////////////////////////////////////////////////////////////////////// +// GetUpdateInfoResponder +class GetUpdateInfoResponder : public LLHTTPClient::ResponderWithCompleted +{ + LOG_CLASS(GetUpdateInfoResponder); + +public: + GetUpdateInfoResponder(std::string type) + : mType(type) + {} + void onNotifyButtonPress(const LLSD& notification, const LLSD& response, std::string name, std::string url) + { + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option == 0) // URL + { + std::string escaped_url = LLWeb::escapeURL(url); + if (gViewerWindow) + { + gViewerWindow->getWindow()->spawnWebBrowser(escaped_url, true); + } + } + if (option == 1) // Later + {} + else if (option == 2) // Ignore + { + LLNotificationPtr notifyptr = LLNotificationsUtil::find(notification["id"]); + if (notifyptr) + { + notifyptr->setIgnored(true); + } + } + } + /*virtual*/ void completedRaw(LLChannelDescriptors const& channels, buffer_ptr_t const& buffer) + { + LLBufferStream istr(channels, buffer.get()); + std::stringstream strstrm; + strstrm << istr.rdbuf(); + const std::string body = strstrm.str(); + + if (mStatus != HTTP_OK) + { + LL_WARNS() << "Failed to get update info (" << mStatus << ")" << LL_ENDL; + return; + } + + Json::Value root; + Json::Reader reader; + if (!reader.parse(body, root)) + { + LL_WARNS() << "Failed to parse update info: " << reader.getFormattedErrorMessages() << LL_ENDL; + return; + } + + std::string viewer_version = llformat("%s (%i)", LLVersionInfo::getShortVersion(), LLVersionInfo::getBuild()); + + const Json::Value data = root[mType]; +#if LL_WINDOWS + std::string recommended_version = data["recommended"]["windows"].asString(); + std::string minimum_version = data["minimum"]["windows"].asString(); +#elif LL_LINUX + std::string recommended_version = data["recommended"]["linux"].asString(); + std::string minimum_version = data["minimum"]["linux"].asString(); +#elif LL_DARWIN + std::string recommended_version = data["recommended"]["apple"].asString(); + std::string minimum_version = data["minimum"]["apple"].asString(); +#endif + + S32 minimum_build, recommended_build; + sscanf(recommended_version.c_str(), "%*i.%*i.%*i (%i)", &recommended_build); + sscanf(minimum_version.c_str(), "%*i.%*i.%*i (%i)", &minimum_build); + + LL_INFOS() << LLVersionInfo::getBuild() << LL_ENDL; + LLSD args; + args["CURRENT_VER"] = viewer_version; + args["RECOMMENDED_VER"] = recommended_version; + args["MINIMUM_VER"] = minimum_version; + args["URL"] = data["url"].asString(); + args["TYPE"] = mType == "release" ? "Viewer" : "Alpha"; + + static LLCachedControl sLastKnownReleaseBuild("SinguLastKnownReleaseBuild", 0); + static LLCachedControl sLastKnownAlphaBuild("SinguLastKnownAlphaBuild", 0); + + LLCachedControl& lastver = mType == "release" ? sLastKnownReleaseBuild : sLastKnownAlphaBuild; + + if (LLVersionInfo::getBuild() < minimum_build || LLVersionInfo::getBuild() < recommended_build) + { + if (lastver.get() < recommended_build) + { + lastver = recommended_build; + LLUI::sIgnoresGroup->setWarning("UrgentUpdateModal", true); + LLUI::sIgnoresGroup->setWarning("UrgentUpdate", true); + LLUI::sIgnoresGroup->setWarning("RecommendedUpdate", true); + } + std::string notificaiton; + if (LLVersionInfo::getBuild() < minimum_build) + { + if (LLUI::sIgnoresGroup->getWarning("UrgentUpdateModal")) + { + notificaiton = "UrgentUpdateModal"; + } + else + { + notificaiton = "UrgentUpdate"; + } + } + else if (LLVersionInfo::getBuild() < recommended_build) + { + notificaiton = "RecommendedUpdate"; + } + if (!notificaiton.empty()) + { + LLNotificationsUtil::add(notificaiton, args, LLSD(), boost::bind(&GetUpdateInfoResponder::onNotifyButtonPress, this, _1, _2, notificaiton, data["url"].asString())); + } + } + } + +protected: + /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return getUpdateInfoResponder_timeout; } + /*virtual*/ char const* getName(void) const { return "GetUpdateInfoResponder"; } + +private: + std::string mType; +}; + +void check_for_updates() +{ +#if LL_WINDOWS | LL_LINUX | LL_DARWIN + // Hard-code the update url for now. + std::string url = "http://singularity-viewer.github.io/pages/api/get_update_info.json";//gSavedSettings.getString("SHUpdateCheckURL"); + if (!url.empty()) + { + std::string type; + auto& channel = LLVersionInfo::getChannel(); + if (channel == std::string("Singularity")) + { + type = "release"; + } + else if (channel == std::string("Singularity Test") || channel == std::string("Singularity Alpha")) + { + type = "alpha"; + } + else + { + return; + } + LLHTTPClient::get(url, new GetUpdateInfoResponder(type)); + } +#endif +} diff --git a/indra/newview/skins/default/xui/en-us/notifications.xml b/indra/newview/skins/default/xui/en-us/notifications.xml index d80695863..28d0a6b0b 100644 --- a/indra/newview/skins/default/xui/en-us/notifications.xml +++ b/indra/newview/skins/default/xui/en-us/notifications.xml @@ -57,20 +57,6 @@ - - +