From cfbc8a23f700f81a3625d55cc3e78ba6d2d315d3 Mon Sep 17 00:00:00 2001 From: Lirusaito Date: Sun, 2 Dec 2012 17:52:36 -0500 Subject: [PATCH] Transaction Notifications are now optionally Notify Tips for those who don't want them to collect at the top right of the screen, but still want a notification. Debug setting LiruNoTransactionClutter has been added, and is toggled by checkbox in General preferences This adds support for TransactionInfo message, to localize the server's transaction notifications. Adds a notification called Payment, which unifies all three of v-d's Payment* notifications. This is a fairly large change to view, keep in mind what was removed as it may just be in a slightly different order or position.. --- indra/newview/app_settings/settings.xml | 11 + indra/newview/llpanelgeneral.cpp | 14 + indra/newview/llpanelgeneral.h | 1 + indra/newview/llviewermessage.cpp | 257 +++++++++++++++++- .../skins/default/xui/en-us/notifications.xml | 8 + .../xui/en-us/panel_preferences_general.xml | 2 + .../skins/default/xui/en-us/strings.xml | 20 +- scripts/messages/message_template.msg | 26 ++ 8 files changed, 325 insertions(+), 14 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 6bae8e6ed..915a147b2 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -693,6 +693,17 @@ Value 0 + LiruNoTransactionClutter + + Comment + Use notifytips for transactions instead of notifys, this way they do not collect in the top right of the screen. + Persist + 1 + Type + Boolean + Value + 0 + LiruSensibleARC Comment diff --git a/indra/newview/llpanelgeneral.cpp b/indra/newview/llpanelgeneral.cpp index fbd323a09..a189d809a 100644 --- a/indra/newview/llpanelgeneral.cpp +++ b/indra/newview/llpanelgeneral.cpp @@ -72,6 +72,7 @@ BOOL LLPanelGeneral::postBuild() childSetValue("show_my_title_checkbox", gSavedSettings.getBOOL("RenderHideGroupTitle")); childSetValue("afk_timeout_spinner", gSavedSettings.getF32("AFKTimeout")); childSetValue("notify_money_change_checkbox", gSavedSettings.getBOOL("NotifyMoneyChange")); + childSetValue("no_transaction_clutter_checkbox", gSavedSettings.getBOOL("LiruNoTransactionClutter")); @@ -111,6 +112,9 @@ BOOL LLPanelGeneral::postBuild() childSetVisible("maturity_desired_combobox", can_choose); childSetVisible("maturity_desired_textbox", !can_choose); + childSetEnabled("no_transaction_clutter_checkbox", gSavedSettings.getBOOL("NotifyMoneyChange")); + childSetCommitCallback("notify_money_change_checkbox", &onClickCheckbox, this); + childSetAction("clear_settings", &onClickClearSettings, this); return TRUE; @@ -147,6 +151,7 @@ void LLPanelGeneral::apply() gSavedSettings.setBOOL("RenderHideGroupTitle", childGetValue("show_my_title_checkbox")); gSavedSettings.setF32("AFKTimeout", childGetValue("afk_timeout_spinner").asReal()); gSavedSettings.setBOOL("NotifyMoneyChange", childGetValue("notify_money_change_checkbox")); + gSavedSettings.setBOOL("LiruNoTransactionClutter", childGetValue("no_transaction_clutter_checkbox")); gSavedSettings.setF32("UIScaleFactor", childGetValue("ui_scale_slider").asReal()); @@ -163,6 +168,15 @@ void LLPanelGeneral::cancel() { } +// static +void LLPanelGeneral::onClickCheckbox(LLUICtrl* ctrl, void* data) +{ + LLPanelGeneral* self = (LLPanelGeneral*)data; + bool enabled = ctrl->getValue().asBoolean(); + if(ctrl->getName() == "notify_money_change_checkbox") + self->childSetEnabled("no_transaction_clutter_checkbox", enabled); +} + // static void LLPanelGeneral::onClickClearSettings(void*) { diff --git a/indra/newview/llpanelgeneral.h b/indra/newview/llpanelgeneral.h index 1249ec8ca..48c44b15c 100644 --- a/indra/newview/llpanelgeneral.h +++ b/indra/newview/llpanelgeneral.h @@ -47,6 +47,7 @@ public: void apply(); void cancel(); + static void onClickCheckbox(LLUICtrl* ctrl, void* data); static void onClickClearSettings(void*); static void callbackResetAllSettings(const LLSD& notification, const LLSD& response); }; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index e3a98c636..1bb0d72e2 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -212,6 +212,7 @@ extern BOOL gDebugClicks; // function prototypes bool check_offer_throttle(const std::string& from_name, bool check_only); void callbackCacheEstateOwnerName(const LLUUID& id, const std::string& full_name, bool is_group); +static void process_money_balance_reply_extended(LLMessageSystem* msg); //inventory offer throttle globals LLFrameTimer gThrottleTimer; @@ -5704,20 +5705,20 @@ void process_money_balance_reply( LLMessageSystem* msg, void** ) gStatusBar->setLandCredit(credit); gStatusBar->setLandCommitted(committed); } - static std::deque recent; - if(!desc.empty() && gSavedSettings.getBOOL("NotifyMoneyChange") - && (std::find(recent.rbegin(), recent.rend(), tid) == recent.rend())) - { - // Make the user confirm the transaction, since they might - // have missed something during an event. - // *TODO:translate - LLSD args; - args["MESSAGE"] = desc; - LLNotificationsUtil::add("SystemMessage", args); - // Also send notification to chat -- MC - LLChat chat(desc); - LLFloaterChat::addChat(desc); + if (desc.empty() + || !gSavedSettings.getBOOL("NotifyMoneyChange")) + { + // ...nothing to display + return; + } + + // Suppress duplicate messages about the same transaction + static std::deque recent; + if (std::find(recent.rbegin(), recent.rend(), tid) != recent.rend()) + { + return; + } // Once the 'recent' container gets large enough, chop some // off the beginning. @@ -5730,6 +5731,236 @@ void process_money_balance_reply( LLMessageSystem* msg, void** ) } //LL_DEBUGS("Messaging") << "Pushing back transaction " << tid << LL_ENDL; recent.push_back(tid); + + if (msg->has("TransactionInfo")) + { + // ...message has extended info for localization + process_money_balance_reply_extended(msg); + } + else + { + // Only old dev grids will not supply the TransactionInfo block, + // so we can just use the hard-coded English string. + LLSD args; + args["MESSAGE"] = desc; + LLNotificationsUtil::add("SystemMessage", args); + + // Also send notification to chat -- MC + LLChat chat(desc); + LLFloaterChat::addChat(desc); + } +} + +static std::string reason_from_transaction_type(S32 transaction_type, + const std::string& item_desc) +{ + // *NOTE: The keys for the reason strings are unusual because + // an earlier version of the code used English language strings + // extracted from hard-coded server English descriptions. + // Keeping them so we don't have to re-localize them. + switch (transaction_type) + { + case TRANS_OBJECT_SALE: + { + LLStringUtil::format_map_t arg; + arg["ITEM"] = item_desc; + return LLTrans::getString("for item", arg); + } + case TRANS_LAND_SALE: + return LLTrans::getString("for a parcel of land"); + + case TRANS_LAND_PASS_SALE: + return LLTrans::getString("for a land access pass"); + + case TRANS_GROUP_LAND_DEED: + return LLTrans::getString("for deeding land"); + + case TRANS_GROUP_CREATE: + return LLTrans::getString("to create a group"); + + case TRANS_GROUP_JOIN: + return LLTrans::getString("to join a group"); + + case TRANS_UPLOAD_CHARGE: + return LLTrans::getString("to upload"); + + case TRANS_CLASSIFIED_CHARGE: + return LLTrans::getString("to publish a classified ad"); + + // These have no reason to display, but are expected and should not + // generate warnings + case TRANS_GIFT: + case TRANS_PAY_OBJECT: + case TRANS_OBJECT_PAYS: + return std::string(); + + default: + llwarns << "Unknown transaction type " + << transaction_type << llendl; + return std::string(); + } +} + +static void process_money_balance_reply_extended(LLMessageSystem* msg) +{ + // Added in server 1.40 and viewer 2.1, support for localization + // and agent ids for name lookup. + S32 transaction_type = 0; + LLUUID source_id; + BOOL is_source_group = false; + LLUUID dest_id; + BOOL is_dest_group = false; + S32 amount = 0; + std::string item_description; + BOOL success = false; + + msg->getS32("TransactionInfo", "TransactionType", transaction_type); + msg->getUUID("TransactionInfo", "SourceID", source_id); + msg->getBOOL("TransactionInfo", "IsSourceGroup", is_source_group); + msg->getUUID("TransactionInfo", "DestID", dest_id); + msg->getBOOL("TransactionInfo", "IsDestGroup", is_dest_group); + msg->getS32("TransactionInfo", "Amount", amount); + msg->getString("TransactionInfo", "ItemDescription", item_description); + msg->getBOOL("MoneyData", "TransactionSuccess", success); + LL_INFOS("Money") << "MoneyBalanceReply source " << source_id + << " dest " << dest_id + << " type " << transaction_type + << " item " << item_description << LL_ENDL; + + if (source_id.isNull() && dest_id.isNull()) + { + // this is a pure balance update, no notification required + return; + } + + static LLCachedControl phoenix_name_system("PhoenixNameSystem", 0); + std::string source_slurl; + if (is_source_group) + { + gCacheName->getGroupName(source_id, source_slurl); + } + else + { + LLAvatarName avatar_name; + if (LLAvatarNameCache::get(source_id, &avatar_name)) + { + switch (phoenix_name_system) + { + case 0 : source_slurl = avatar_name.getLegacyName(); break; + case 1 : source_slurl = avatar_name.getCompleteName(); break; + case 2 : source_slurl = avatar_name.mDisplayName; break; + default : source_slurl = avatar_name.getLegacyName(); break; + } + } + } + + std::string dest_slurl; + if (is_dest_group) + { + gCacheName->getGroupName(dest_id, dest_slurl); + } + else + { + LLAvatarName avatar_name; + if (LLAvatarNameCache::get(dest_id, &avatar_name)) + { + switch (phoenix_name_system) + { + case 0 : dest_slurl = avatar_name.getLegacyName(); break; + case 1 : dest_slurl = avatar_name.getCompleteName(); break; + case 2 : dest_slurl = avatar_name.mDisplayName; break; + default : dest_slurl = avatar_name.getLegacyName(); break; + } + } + } + + std::string reason = + reason_from_transaction_type(transaction_type, item_description); + + LLStringUtil::format_map_t args; + args["REASON"] = reason; // could be empty + args["AMOUNT"] = llformat("%d", amount); + + // Need to delay until name looked up, so need to know whether or not + // is group + bool is_name_group = false; + LLUUID name_id; + std::string message; + static LLCachedControl no_transaction_clutter("LiruNoTransactionClutter", false); + std::string notification = no_transaction_clutter ? "Payment" : "SystemMessage"; + LLSD final_args; + LLSD payload; + + bool you_paid_someone = (source_id == gAgentID); + if (you_paid_someone) + { + args["NAME"] = dest_slurl; + is_name_group = is_dest_group; + name_id = dest_id; + if (!reason.empty()) + { + if (dest_id.notNull()) + { + message = success ? LLTrans::getString("you_paid_ldollars", args) : + LLTrans::getString("you_paid_failure_ldollars", args); + } + else + { + // transaction fee to the system, eg, to create a group + message = success ? LLTrans::getString("you_paid_ldollars_no_name", args) : + LLTrans::getString("you_paid_failure_ldollars_no_name", args); + } + } + else + { + if (dest_id.notNull()) + { + message = success ? LLTrans::getString("you_paid_ldollars_no_reason", args) : + LLTrans::getString("you_paid_failure_ldollars_no_reason", args); + } + else + { + // no target, no reason, you just paid money + message = success ? LLTrans::getString("you_paid_ldollars_no_info", args) : + LLTrans::getString("you_paid_failure_ldollars_no_info", args); + } + } + final_args["MESSAGE"] = message; + } + else + { + // ...someone paid you + args["NAME"] = source_slurl; + is_name_group = is_source_group; + name_id = source_id; + if (!reason.empty()) + { + message = LLTrans::getString("paid_you_ldollars", args); + } + else + { + message = LLTrans::getString("paid_you_ldollars_no_reason", args); + } + final_args["MESSAGE"] = message; + + // make notification loggable + payload["from_id"] = source_id; + } + + // Despite using SLURLs, wait until the name is available before + // showing the notification, otherwise the UI layout is strange and + // the user sees a "Loading..." message + if (is_name_group) + { + gCacheName->getGroup(name_id, + boost::bind(&LLNotificationsUtil::add, + notification, final_args, payload)); + } + else + { + LLAvatarNameCache::get(name_id, + boost::bind(&LLNotificationsUtil::add, + notification, final_args, payload)); } } diff --git a/indra/newview/skins/default/xui/en-us/notifications.xml b/indra/newview/skins/default/xui/en-us/notifications.xml index acb78b1f4..5a737ba85 100644 --- a/indra/newview/skins/default/xui/en-us/notifications.xml +++ b/indra/newview/skins/default/xui/en-us/notifications.xml @@ -5880,6 +5880,14 @@ Please select at least one type of content to search (PG, Mature, or Adult). [MESSAGE] + + funds +[MESSAGE] + + + + Rating: I want to access content rated: diff --git a/indra/newview/skins/default/xui/en-us/strings.xml b/indra/newview/skins/default/xui/en-us/strings.xml index 89aabcb73..ef65e554c 100644 --- a/indra/newview/skins/default/xui/en-us/strings.xml +++ b/indra/newview/skins/default/xui/en-us/strings.xml @@ -3872,9 +3872,27 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. Home position set. - This costs [CURRENCY] + [NAME] paid you L$[AMOUNT] [REASON]. + [NAME] paid you L$[AMOUNT]. + You paid [NAME] L$[AMOUNT] [REASON]. + You paid L$[AMOUNT]. + You paid [NAME] L$[AMOUNT]. + You paid L$[AMOUNT] [REASON]. + You failed to pay [NAME] L$[AMOUNT] [REASON]. + You failed to pay L$[AMOUNT]. + You failed to pay [NAME] L$[AMOUNT]. + You failed to pay L$[AMOUNT] [REASON]. + for [ITEM] + for a parcel of land + for a land access pass + for deeding land + to create a group + to join a group + to upload + to publish a classified ad Giving [CURRENCY] + This costs [CURRENCY] Everyone Officers diff --git a/scripts/messages/message_template.msg b/scripts/messages/message_template.msg index 2ffe8a79a..6bf56790f 100644 --- a/scripts/messages/message_template.msg +++ b/scripts/messages/message_template.msg @@ -6775,6 +6775,8 @@ version 2.0 } // And, the money transfer +// *NOTE: Unused as of 2010-04-06, because all back-end money transactions +// are done with web services via L$ API. JC { MoneyTransferBackend Low 312 Trusted Zerocoded { @@ -6825,6 +6827,19 @@ version 2.0 { SquareMetersCommitted S32 } { Description Variable 1 } // string } + // For replies that are part of a transaction (buying something) provide + // metadata for localization. If TransactionType is 0, the message is + // purely a balance update. Added for server 1.40 and viewer 2.1. JC + { + TransactionInfo Single + { TransactionType S32 } // lltransactiontype.h + { SourceID LLUUID } + { IsSourceGroup BOOL } + { DestID LLUUID } + { IsDestGroup BOOL } + { Amount S32 } + { ItemDescription Variable 1 } // string + } } @@ -6851,6 +6866,17 @@ version 2.0 { SquareMetersCommitted S32 } { Description Variable 1 } // string } + // See MoneyBalanceReply above. + { + TransactionInfo Single + { TransactionType S32 } // lltransactiontype.h + { SourceID LLUUID } + { IsSourceGroup BOOL } + { DestID LLUUID } + { IsDestGroup BOOL } + { Amount S32 } + { ItemDescription Variable 1 } // string + } }