From 60d28437e616a6afda51a368ea40ad49a707d16c Mon Sep 17 00:00:00 2001
From: pavelk_productengine <pavelkproductengine@lindenlab.com>
Date: Wed, 8 Apr 2015 19:51:39 +0300
Subject: [PATCH] MAINT-4734 (Separate transaction notices from group
 notice/invites)  1) added GroupNotice notification type and tab "Group" for
 it;  2) added Attachment field to group notice notifications which may
 contain inventory offers, notecards,  etc;  3) added Fee field to Group
 Invite notifications;  4) added notification resize depending on attachment
 field.

---
 .../newview/llfloaternotificationstabbed.cpp  |  24 ++-
 indra/newview/llfloaternotificationstabbed.h  |   3 +-
 indra/newview/llnotificationlistitem.cpp      | 166 ++++++++++++++----
 indra/newview/llnotificationlistitem.h        |  82 +++++++--
 indra/newview/lltoastgroupnotifypanel.cpp     |   2 +-
 indra/newview/llviewermessage.cpp             |   1 +
 .../skins/default/textures/textures.xml       |   2 +
 .../xui/en/floater_notifications_tabbed.xml   |  29 ++-
 .../xui/en/panel_notification_list_item.xml   |  69 +++++---
 9 files changed, 289 insertions(+), 89 deletions(-)

diff --git a/indra/newview/llfloaternotificationstabbed.cpp b/indra/newview/llfloaternotificationstabbed.cpp
index 05a0af01ce3..fd5f1486d96 100644
--- a/indra/newview/llfloaternotificationstabbed.cpp
+++ b/indra/newview/llfloaternotificationstabbed.cpp
@@ -41,7 +41,8 @@
 LLFloaterNotificationsTabbed::LLFloaterNotificationsTabbed(const LLSD& key) : LLTransientDockableFloater(NULL, true,  key),
     mChannel(NULL),
     mSysWellChiclet(NULL),
-    mInviteMessageList(NULL),
+    mGroupInviteMessageList(NULL),
+    mGroupNoticeMessageList(NULL),
     mTransactionMessageList(NULL),
     mSystemMessageList(NULL),
     mNotificationsSeparator(NULL),
@@ -59,10 +60,12 @@ LLFloaterNotificationsTabbed::LLFloaterNotificationsTabbed(const LLSD& key) : LL
 //---------------------------------------------------------------------------------
 BOOL LLFloaterNotificationsTabbed::postBuild()
 {
-    mInviteMessageList = getChild<LLNotificationListView>("invite_notification_list");
+    mGroupInviteMessageList = getChild<LLNotificationListView>("group_invite_notification_list");
+    mGroupNoticeMessageList = getChild<LLNotificationListView>("group_notice_notification_list");
     mTransactionMessageList = getChild<LLNotificationListView>("transaction_notification_list");
     mSystemMessageList = getChild<LLNotificationListView>("system_notification_list");
-    mNotificationsSeparator->initTaggedList(LLNotificationListItem::getInviteTypes(), mInviteMessageList);
+    mNotificationsSeparator->initTaggedList(LLNotificationListItem::getGroupInviteTypes(), mGroupInviteMessageList);
+    mNotificationsSeparator->initTaggedList(LLNotificationListItem::getGroupNoticeTypes(), mGroupNoticeMessageList);
     mNotificationsSeparator->initTaggedList(LLNotificationListItem::getTransactionTypes(), mTransactionMessageList);
     mNotificationsSeparator->initUnTaggedList(mSystemMessageList);
     mNotificationsTabContainer = getChild<LLTabContainer>("notifications_tab_container");
@@ -257,7 +260,8 @@ void LLFloaterNotificationsTabbed::updateNotificationCounters()
 {
     updateNotificationCounter(0, mSystemMessageList->size(), "system_tab_title");
     updateNotificationCounter(1, mTransactionMessageList->size(), "transactions_tab_title");
-    updateNotificationCounter(2, mInviteMessageList->size(), "invitations_tab_title");
+    updateNotificationCounter(2, mGroupInviteMessageList->size(), "group_invitations_tab_title");
+    updateNotificationCounter(3, mGroupNoticeMessageList->size(), "group_notices_tab_title");
 }
 
 //---------------------------------------------------------------------------------
@@ -316,7 +320,10 @@ void LLFloaterNotificationsTabbed::getAllItemsOnCurrentTab(std::vector<LLPanel*>
         mTransactionMessageList->getItems(items);
         break;
     case 2:
-        mInviteMessageList->getItems(items);
+        mGroupInviteMessageList->getItems(items);
+        break;
+    case 3:
+        mGroupNoticeMessageList->getItems(items);
         break;
     default:
         break;
@@ -379,10 +386,15 @@ void LLFloaterNotificationsTabbed::onStoreToast(LLPanel* info_panel, LLUUID id)
     LLSD payload = notify->getPayload();
     p.notification_name = notify->getName();
     p.group_id = payload["group_id"];
-    p.sender = payload["name"].asString();
+    p.fee =  payload["fee"];
+    p.subject = payload["subject"].asString();
+    p.message = payload["message"].asString();
+    p.sender = payload["sender_name"].asString();
     p.time_stamp = notify->getDate();
+    p.received_time = payload["received_time"].asDate();
     p.paid_from_id = payload["from_id"];
     p.paid_to_id = payload["dest_id"];
+    p.inventory_offer = payload["inventory_offer"];
     addItem(p);
 }
 
diff --git a/indra/newview/llfloaternotificationstabbed.h b/indra/newview/llfloaternotificationstabbed.h
index 5191b783f63..8dd20b18c42 100644
--- a/indra/newview/llfloaternotificationstabbed.h
+++ b/indra/newview/llfloaternotificationstabbed.h
@@ -158,7 +158,8 @@ class LLFloaterNotificationsTabbed : public LLTransientDockableFloater
     // ID of a toast loaded by user (by clicking notification well item)
     LLUUID mLoadedToastId;
 
-    LLNotificationListView*	mInviteMessageList;
+    LLNotificationListView*	mGroupInviteMessageList;
+    LLNotificationListView*	mGroupNoticeMessageList;
     LLNotificationListView*	mTransactionMessageList;
     LLNotificationListView*	mSystemMessageList;
     LLNotificationSeparator* mNotificationsSeparator;
diff --git a/indra/newview/llnotificationlistitem.cpp b/indra/newview/llnotificationlistitem.cpp
index 4c4dd07d7fa..6b674fcc7d4 100644
--- a/indra/newview/llnotificationlistitem.cpp
+++ b/indra/newview/llnotificationlistitem.cpp
@@ -29,10 +29,13 @@
 
 #include "llnotificationlistitem.h"
 
+#include "llagent.h"
+#include "llinventoryicon.h"
 #include "llwindow.h"
 #include "v4color.h"
 #include "lltrans.h"
 #include "lluicolortable.h"
+#include "message.h"
 
 LLNotificationListItem::LLNotificationListItem(const Params& p) : LLPanel(p),
     mParams(p),
@@ -42,7 +45,9 @@ LLNotificationListItem::LLNotificationListItem(const Params& p) : LLPanel(p),
     mCloseBtn(NULL),
     mCondensedViewPanel(NULL),
     mExpandedViewPanel(NULL),
-    mMainPanel(NULL)
+    mCondensedHeight(0),
+    mExpandedHeight(0),
+    mExpandedHeightResize(0)
 {
     mNotificationName = p.notification_name;
 }
@@ -60,7 +65,6 @@ BOOL LLNotificationListItem::postBuild()
     mCondenseBtn = getChild<LLButton>("condense_btn");
     mCloseBtn = getChild<LLButton>("close_btn");
     mCloseBtnExp = getChild<LLButton>("close_expanded_btn");
-    mVerticalStack = getChild<LLLayoutStack>("item_vertical_stack");
 
     mTitleBox->setValue(mParams.title);
     mTitleBoxExp->setValue(mParams.title);
@@ -78,14 +82,13 @@ BOOL LLNotificationListItem::postBuild()
 
     mCondensedViewPanel = getChild<LLPanel>("layout_panel_condensed_view");
     mExpandedViewPanel = getChild<LLPanel>("layout_panel_expanded_view");
-    mMainPanel = getChild<LLPanel>("main_panel");
 
-    std::string expanded_heigt_str = getString("item_expanded_height");
-    std::string condensed_heigt_str = getString("item_condensed_height");
-
-    mExpandedHeight = (S32)atoi(expanded_heigt_str.c_str());
-    mCondensedHeight = (S32)atoi(condensed_heigt_str.c_str());
+    std::string expanded_height_str = getString("item_expanded_height");
+    std::string condensed_height_str = getString("item_condensed_height");
 
+    mExpandedHeight = (S32)atoi(expanded_height_str.c_str());
+    mCondensedHeight = (S32)atoi(condensed_height_str.c_str());
+    
     setExpanded(FALSE);
     return rv;
 }
@@ -124,9 +127,13 @@ BOOL LLNotificationListItem::handleMouseUp(S32 x, S32 y, MASK mask)
 //static
 LLNotificationListItem* LLNotificationListItem::create(const Params& p)
 {
-    if (LLNotificationListItem::getInviteTypes().count(p.notification_name))
+    if (LLNotificationListItem::getGroupInviteTypes().count(p.notification_name))
+    {
+        return new LLGroupInviteNotificationListItem(p);
+    }
+    else if (LLNotificationListItem::getGroupNoticeTypes().count(p.notification_name))
     {
-        return new LLInviteNotificationListItem(p);
+        return new LLGroupNoticeNotificationListItem(p);
     }
     else if (LLNotificationListItem::getTransactionTypes().count(p.notification_name))
     {
@@ -136,9 +143,15 @@ LLNotificationListItem* LLNotificationListItem::create(const Params& p)
 }
 
 //static
-std::set<std::string> LLNotificationListItem::getInviteTypes() 
+std::set<std::string> LLNotificationListItem::getGroupInviteTypes() 
+{
+    return LLGroupInviteNotificationListItem::getTypes();
+}
+
+
+std::set<std::string> LLNotificationListItem::getGroupNoticeTypes()
 {
-    return LLInviteNotificationListItem::getTypes();
+    return LLGroupNoticeNotificationListItem::getTypes();
 }
 
 //static
@@ -164,7 +177,7 @@ void LLNotificationListItem::setExpanded(BOOL value)
     S32 width = this->getRect().getWidth();
     if (value)
     {
-        this->reshape(width, mExpandedHeight, FALSE);
+        this->reshape(width, mExpandedHeight + mExpandedHeightResize, FALSE);
     }
     else
     {
@@ -172,13 +185,20 @@ void LLNotificationListItem::setExpanded(BOOL value)
     }
 }
 
-std::set<std::string> LLInviteNotificationListItem::getTypes()
+std::set<std::string> LLGroupInviteNotificationListItem::getTypes()
 {
     std::set<std::string> types;
     types.insert("JoinGroup");
     return types;
 }
 
+std::set<std::string> LLGroupNoticeNotificationListItem::getTypes()
+{
+    std::set<std::string> types;
+    types.insert("GroupNotice");
+    return types;
+}
+
 std::set<std::string> LLTransactionNotificationListItem::getTypes()
 {
     std::set<std::string> types;
@@ -187,14 +207,94 @@ std::set<std::string> LLTransactionNotificationListItem::getTypes()
     return types;
 }
 
-LLInviteNotificationListItem::LLInviteNotificationListItem(const Params& p)
+LLGroupNotificationListItem::LLGroupNotificationListItem(const Params& p)
     : LLNotificationListItem(p),
-    mSenderBox(NULL)
+    mSenderOrFeeBox(NULL)
+{
+}
+
+LLGroupInviteNotificationListItem::LLGroupInviteNotificationListItem(const Params& p)
+    : LLGroupNotificationListItem(p)
+{
+    buildFromFile("panel_notification_list_item.xml");
+}
+
+BOOL LLGroupInviteNotificationListItem::postBuild()
+{
+    BOOL rv = LLGroupNotificationListItem::postBuild();
+    setFee(mParams.fee);
+    return rv;
+}
+
+void LLGroupInviteNotificationListItem::setFee(S32 fee)
+{
+    LLStringUtil::format_map_t string_args;
+    string_args["[GROUP_FEE]"] = llformat("%d", fee);
+    std::string fee_text = getString("group_fee_text", string_args);
+    mSenderOrFeeBox->setValue(fee_text);
+    mSenderOrFeeBoxExp->setValue(fee_text);
+    mSenderOrFeeBox->setVisible(TRUE);
+    mSenderOrFeeBoxExp->setVisible(TRUE);
+}
+
+LLGroupNoticeNotificationListItem::LLGroupNoticeNotificationListItem(const Params& p)
+    : LLGroupNotificationListItem(p),
+    mAttachmentPanel(NULL),
+    mAttachmentTextBox(NULL),
+    mAttachmentIcon(NULL),
+    mAttachmentIconExp(NULL),
+    mInventoryOffer(NULL)
 {
+    if (mParams.inventory_offer.isDefined())
+    {
+        mInventoryOffer = new LLOfferInfo(mParams.inventory_offer);
+    }
+
     buildFromFile("panel_notification_list_item.xml");
 }
 
-BOOL LLInviteNotificationListItem::postBuild()
+BOOL LLGroupNoticeNotificationListItem::postBuild()
+{
+    BOOL rv = LLGroupNotificationListItem::postBuild();
+
+    mAttachmentTextBox = getChild<LLTextBox>("attachment_text");
+    mAttachmentIcon = getChild<LLIconCtrl>("attachment_icon");
+    mAttachmentIconExp = getChild<LLIconCtrl>("attachment_icon_exp");
+    mAttachmentPanel = getChild<LLPanel>("attachment_panel");
+    mAttachmentPanel->setVisible(FALSE);
+
+
+    mTitleBox->setValue(mParams.subject);
+    mTitleBoxExp->setValue(mParams.subject);
+    mNoticeTextExp->setValue(mParams.message);
+    //Workaround: in case server timestamp is 0 - we use the time when notification was actually received
+    if (mParams.time_stamp.isNull())
+    {
+        mTimeBox->setValue(buildNotificationDate(mParams.received_time));
+        mTimeBoxExp->setValue(buildNotificationDate(mParams.received_time));
+    }
+    setSender(mParams.sender);
+
+    if (mInventoryOffer != NULL)
+    {
+        mAttachmentTextBox->setValue(mInventoryOffer->mDesc);
+        mAttachmentIcon->setVisible(TRUE);
+
+        std::string icon_name = LLInventoryIcon::getIconName(mInventoryOffer->mType,
+          LLInventoryType::IT_TEXTURE);
+
+        mAttachmentIconExp->setValue(icon_name);
+        mAttachmentIconExp->setVisible(TRUE);
+
+        std::string expanded_height_resize_str = getString("expanded_height_resize_for_attachment");
+        mExpandedHeightResize = (S32)atoi(expanded_height_resize_str.c_str());
+
+        mAttachmentPanel->setVisible(TRUE);
+    }
+    return rv;
+}
+
+BOOL LLGroupNotificationListItem::postBuild()
 {
     BOOL rv = LLNotificationListItem::postBuild();
 
@@ -210,10 +310,8 @@ BOOL LLInviteNotificationListItem::postBuild()
 
     mGroupId = mParams.group_id;
 
-    mSenderBox = getChild<LLTextBox>("sender_resident");
-    mSenderBoxExp = getChild<LLTextBox>("sender_resident_exp");
-
-    setSender(mParams.sender);
+    mSenderOrFeeBox = getChild<LLTextBox>("sender_or_fee_box");
+    mSenderOrFeeBoxExp = getChild<LLTextBox>("sender_or_fee_box_exp");
 
     LLSD value(mParams.group_id);
     setGroupId(value);
@@ -221,7 +319,7 @@ BOOL LLInviteNotificationListItem::postBuild()
     return rv;
 }
 
-void LLInviteNotificationListItem::changed(LLGroupChange gc)
+void LLGroupNotificationListItem::changed(LLGroupChange gc)
 {
     if (GC_PROPERTIES == gc)
     {
@@ -229,7 +327,7 @@ void LLInviteNotificationListItem::changed(LLGroupChange gc)
     }
 }
 
-bool LLInviteNotificationListItem::updateFromCache()
+bool LLGroupNotificationListItem::updateFromCache()
 {
     LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(mGroupId);
     if (!group_data) return false;
@@ -237,7 +335,7 @@ bool LLInviteNotificationListItem::updateFromCache()
     return true;
 }
 
-void LLInviteNotificationListItem::setGroupId(const LLUUID& value)
+void LLGroupNotificationListItem::setGroupId(const LLUUID& value)
 {
     LLGroupMgr* gm = LLGroupMgr::getInstance();
     if (mGroupId.notNull())
@@ -255,7 +353,7 @@ void LLInviteNotificationListItem::setGroupId(const LLUUID& value)
     }
 }
 
-void LLInviteNotificationListItem::setGroupName(std::string name)
+void LLGroupNotificationListItem::setGroupName(std::string name)
 {
     if (!name.empty())
     {
@@ -272,22 +370,22 @@ void LLInviteNotificationListItem::setGroupName(std::string name)
     }
 }
 
-void LLInviteNotificationListItem::setSender(std::string sender)
+void LLGroupNoticeNotificationListItem::setSender(std::string sender)
 {
     if (!sender.empty())
     {
         LLStringUtil::format_map_t string_args;
         string_args["[SENDER_RESIDENT]"] = llformat("%s", sender.c_str());
         std::string sender_text = getString("sender_resident_text", string_args);
-        mSenderBox->setValue(sender_text);
-        mSenderBox->setVisible(TRUE);
-        mSenderBoxExp->setValue(sender_text);
-        mSenderBoxExp->setVisible(TRUE);
+        mSenderOrFeeBox->setValue(sender_text);
+        mSenderOrFeeBoxExp->setValue(sender_text);
+        mSenderOrFeeBox->setVisible(TRUE);
+        mSenderOrFeeBoxExp->setVisible(TRUE);
     } else {
-        mSenderBox->setValue(LLStringUtil::null);
-        mSenderBoxExp->setValue(LLStringUtil::null);
-        mSenderBox->setVisible(FALSE);
-        mSenderBoxExp->setVisible(FALSE);
+        mSenderOrFeeBox->setValue(LLStringUtil::null);
+        mSenderOrFeeBoxExp->setValue(LLStringUtil::null);
+        mSenderOrFeeBox->setVisible(FALSE);
+        mSenderOrFeeBoxExp->setVisible(FALSE);
     }
 }
 
diff --git a/indra/newview/llnotificationlistitem.h b/indra/newview/llnotificationlistitem.h
index 22003a3a6a8..bd76d17fe8a 100644
--- a/indra/newview/llnotificationlistitem.h
+++ b/indra/newview/llnotificationlistitem.h
@@ -35,6 +35,7 @@
 #include "llavatariconctrl.h"
 
 #include "llgroupmgr.h"
+#include "llviewermessage.h"
 
 #include <string>
 
@@ -49,15 +50,21 @@ class LLNotificationListItem : public LLPanel
         LLUUID          paid_to_id;
         std::string     notification_name;
         std::string     title;
+        std::string     subject;
+        std::string     message;
         std::string     sender;
-        LLDate time_stamp;
+        S32             fee;
+        LLDate          time_stamp;
+        LLDate          received_time;
+        LLSD            inventory_offer;
         Params()        {};
     };
 
     static LLNotificationListItem* create(const Params& p);
 
-    static std::set<std::string> getInviteTypes();
     static std::set<std::string> getTransactionTypes();
+    static std::set<std::string> getGroupInviteTypes();
+    static std::set<std::string> getGroupNoticeTypes();
 
     // title
     void setTitle( std::string title );
@@ -99,43 +106,80 @@ class LLNotificationListItem : public LLPanel
     LLButton*   mCondenseBtn;
     LLButton*   mCloseBtn;
     LLButton*   mCloseBtnExp;
-    LLLayoutStack* mVerticalStack;
     LLPanel*    mCondensedViewPanel;
     LLPanel*    mExpandedViewPanel;
-    LLPanel*    mMainPanel;
     std::string mTitle;
     std::string mNotificationName;
-    S32 mCondensedHeight;
-    S32 mExpandedHeight;
+    S32         mCondensedHeight;
+    S32         mExpandedHeight;
+    S32         mExpandedHeightResize;
 };
 
-class LLInviteNotificationListItem
+class LLGroupNotificationListItem
     : public LLNotificationListItem, public LLGroupMgrObserver
 {
 public:
-    static std::set<std::string> getTypes();
     virtual BOOL postBuild();
 
     void setGroupId(const LLUUID& value);
     // LLGroupMgrObserver observer trigger
     virtual void changed(LLGroupChange gc);
-private:
-    friend class LLNotificationListItem;
-    LLInviteNotificationListItem(const Params& p);
-    LLInviteNotificationListItem(const LLInviteNotificationListItem &);
-    LLInviteNotificationListItem & operator=(LLInviteNotificationListItem &);
 
-    void setSender(std::string sender);
-    void setGroupName(std::string name);
-
-    bool updateFromCache();
+    friend class LLNotificationListItem;
+protected:
+    LLGroupNotificationListItem(const Params& p);
 
     LLGroupIconCtrl* mGroupIcon;
     LLGroupIconCtrl* mGroupIconExp;
     LLUUID      mGroupId;
-    LLTextBox*  mSenderBox;
-    LLTextBox*  mSenderBoxExp;
+    LLTextBox*  mSenderOrFeeBox;
+    LLTextBox*  mSenderOrFeeBoxExp;
     LLTextBox*  mGroupNameBoxExp;
+
+private:
+    LLGroupNotificationListItem(const LLGroupNotificationListItem &);
+    LLGroupNotificationListItem & operator=(LLGroupNotificationListItem &);
+
+    void setGroupName(std::string name);
+    bool updateFromCache();
+};
+
+class LLGroupInviteNotificationListItem
+    : public LLGroupNotificationListItem
+{
+public:
+    static std::set<std::string> getTypes();
+    virtual BOOL postBuild();
+
+private:
+    friend class LLNotificationListItem;
+    LLGroupInviteNotificationListItem(const Params& p);
+    LLGroupInviteNotificationListItem(const LLGroupInviteNotificationListItem &);
+    LLGroupInviteNotificationListItem & operator=(LLGroupInviteNotificationListItem &);
+
+    void setFee(S32 fee);
+};
+
+class LLGroupNoticeNotificationListItem
+    : public LLGroupNotificationListItem
+{
+public:
+    static std::set<std::string> getTypes();
+    virtual BOOL postBuild();
+
+private:
+    friend class LLNotificationListItem;
+    LLGroupNoticeNotificationListItem(const Params& p);
+    LLGroupNoticeNotificationListItem(const LLGroupNoticeNotificationListItem &);
+    LLGroupNoticeNotificationListItem & operator=(LLGroupNoticeNotificationListItem &);
+
+    void setSender(std::string sender);
+
+    LLPanel*    mAttachmentPanel;
+    LLTextBox*  mAttachmentTextBox;
+    LLIconCtrl* mAttachmentIcon;
+    LLIconCtrl* mAttachmentIconExp;
+    LLOfferInfo* mInventoryOffer;
 };
 
 class LLTransactionNotificationListItem : public LLNotificationListItem
diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp
index e00b18dedbe..def5a0ac7ca 100755
--- a/indra/newview/lltoastgroupnotifypanel.cpp
+++ b/indra/newview/lltoastgroupnotifypanel.cpp
@@ -92,7 +92,7 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(const LLNotificationPtr& notifi
 							+LLTrans::getString("UTCTimeSec")+"] ["
 							+LLTrans::getString("UTCTimeTimezone")+"]";
 	const LLDate timeStamp = notification->getDate();
-	LLDate notice_date = timeStamp.notNull() ? timeStamp : LLDate::now();
+	LLDate notice_date = timeStamp.notNull() ? timeStamp : payload["received_time"];
 	LLSD substitution;
 	substitution["datetime"] = (S32) notice_date.secondsSinceEpoch();
 	LLStringUtil::format(timeStr, substitution);
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 6507794cdd4..99db3ff0933 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -2681,6 +2681,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 				payload["sender_name"] = name;
 				payload["group_id"] = group_id;
 				payload["inventory_name"] = item_name;
+ 				payload["received_time"] = LLDate::now();
 				if(info && info->asLLSD())
 				{
 					payload["inventory_offer"] = info->asLLSD();
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index e47e0c03f14..4f8962182e3 100755
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -798,4 +798,6 @@ with the same filename but different name
   <texture name="Notification_Condense" file_name="icons/Icon_Notification_Condense.png" preload="true"/>
   <texture name="Notification_Expand" file_name="icons/Icon_Notification_Expand.png" preload="true"/>
   <texture name="System_Notification" file_name="icons/SL_Logo.png" preload="true"/>
+  <texture name="Icon_Attachment_Small" file_name="icons/Icon_Attachment_Small.png"	preload="true"/>
+  <texture name="Icon_Attachment_Large" file_name="icons/Icon_Attachment_Large.png"	preload="true"/>
 </textures>
diff --git a/indra/newview/skins/default/xui/en/floater_notifications_tabbed.xml b/indra/newview/skins/default/xui/en/floater_notifications_tabbed.xml
index 55ecfb637b4..0fdd9ed0c67 100644
--- a/indra/newview/skins/default/xui/en/floater_notifications_tabbed.xml
+++ b/indra/newview/skins/default/xui/en/floater_notifications_tabbed.xml
@@ -28,9 +28,13 @@
     Transactions ([COUNT])
   </floater.string>
   <floater.string
-    name="invitations_tab_title">
+    name="group_invitations_tab_title">
     Invitations ([COUNT])
   </floater.string>
+  <floater.string
+    name="group_notices_tab_title">
+    Group ([COUNT])
+  </floater.string>
 
   <string
    name="title_notification_tabbed_window">
@@ -72,7 +76,7 @@
        follows="left|top|right|bottom"
        label="Transactions (0)"
        layout="topleft"
-       name="TransactionNotificationsTab">
+       name="transaction_notifications_tab">
         <notification_list_view
           color="FloaterDefaultBackgroundColor"
           follows="all"
@@ -89,12 +93,29 @@
        follows="left|top|right|bottom"
        label="Invitations (0)"
        layout="topleft"
-       name="InviteNotificationsTab">
+       name="group_invite_notifications_tab">
+        <notification_list_view
+          color="FloaterDefaultBackgroundColor"
+          follows="all"
+          layout="topleft"
+          name="group_invite_notification_list"
+          left="0"
+          top="5"
+          height="0"
+          width="328"/>
+      </panel>
+      <panel
+       border="true"
+       bevel_style="none"
+       follows="left|top|right|bottom"
+       label="Group (0)"
+       layout="topleft"
+       name="group_notice_notifications_tab">
         <notification_list_view
           color="FloaterDefaultBackgroundColor"
           follows="all"
           layout="topleft"
-          name="invite_notification_list"
+          name="group_notice_notification_list"
           left="0"
           top="5"
           height="0"
diff --git a/indra/newview/skins/default/xui/en/panel_notification_list_item.xml b/indra/newview/skins/default/xui/en/panel_notification_list_item.xml
index 55456723a23..7b57cddd7b7 100644
--- a/indra/newview/skins/default/xui/en/panel_notification_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_notification_list_item.xml
@@ -8,7 +8,7 @@
   top="0"
   left="0"
   width="331"
-  height="200"
+  height="202"
   can_resize="true"
   layout="topleft"
   follows="left|top|right|bottom"
@@ -23,18 +23,26 @@
     name="group_name_text">
     Group: "[GROUP_NAME]"
   </panel.string>
+  <panel.string
+    name="group_fee_text">
+    Fee: [GROUP_FEE]
+  </panel.string>
   <panel.string
     name="item_condensed_height">
     50
   </panel.string>
   <panel.string
     name="item_expanded_height">
-    200
+    175
+  </panel.string>
+  <panel.string
+    name="expanded_height_resize_for_attachment">
+    27
   </panel.string>
 
   <panel top="0" left="0" width="331" height="196" bevel_style="none" layout="topleft" follows="left|top|right|bottom" name="panel_total_view">
   <layout_stack top="0" left="0" width="331" height="196" orientation="vertical" follows="left|top|right|bottom" name="item_vertical_stack">
-  <layout_panel top="0" left="0" height="30" layout="topleft" follows="left|top|right|bottom" name="layout_panel_condensed_view" visible="false">
+  <layout_panel top="0" left="0" height="30" follows="left|top|right|bottom" layout="topleft" name="layout_panel_condensed_view" visible="false">
     <panel border="true" top="0" left="5" height="30" bevel_style="none" layout="topleft" follows="left|top|right|bottom" name="panel_condensed_view">
       <layout_stack top="0" left="0" width="325" height="50" orientation="horizontal" follows="left|top|right|bottom" name="horizontal_stack">
       <layout_panel width="30" height="39" orientation="horizontal" follows="left|top|right|bottom" name="layout_panel_right">
@@ -49,10 +57,11 @@
               use_ellipses="true" word_wrap="true" mouse_opaque="false" name="notification_title" >
               Group Name:Notice Title N o t i c e T i t l e N o t i c e T i t l e N o t i c e T i t l e N oticeTitle
             </text>
+            <icon top="0" left="242" width="21" height="21" image_name="Icon_Attachment_Small" follows="right" mouse_opaque="true" name="attachment_icon" tool_tip="Attachment" visible="false"/>
           </panel>
           <panel border="false" top="23" left="0" width="260" height="15" bevel_style="none" follows="left|top|right|bottom" layout="topleft" name="sender_time_panel">
             <text allow_scroll="false" font="SansSerifSmall" top="0" left="0" width="170" height="13" layout="topleft" follows="right|left"
-              use_ellipses="true" word_wrap="false" mouse_opaque="false" name="sender_resident" visible="false">
+              use_ellipses="true" word_wrap="false" mouse_opaque="false" name="sender_or_fee_box" visible="false">
               Sender: "Resident R e s i d e n t R e s i d e n t"
             </text>
             <text allow_scroll="false" font="SansSerifSmall" top="0" right="-5" width="95" height="13" follows="right" halign="right" layout="topleft" left_pad="5"
@@ -60,27 +69,30 @@
           </panel>
         </panel>
       </layout_panel>
-      <layout_panel width="18" height="48" orientation="horizontal" follows="left|top" name="layout_panel_right">
-        <panel top="0" left="0" width="17"  height="39" follows="left|top" layout="topleft" name="close_expand_panel">
-          <button top="0" left="1" width="17" height="17" layout="topleft" follows="top" name="close_btn" mouse_opaque="true"
+      <layout_panel width="18" height="48" orientation="horizontal" follows="right|top|bottom" name="layout_panel_right">
+        <panel top="0" left="0" width="17"  height="39" follows="left|top|right|bottom" layout="topleft" name="close_expand_panel">
+          <button top="0" left="0" width="17" height="17" layout="topleft" follows="top" name="close_btn" mouse_opaque="true"
             tab_stop="false" image_unselected="Icon_Close_Foreground" image_selected="Icon_Close_Press" />
-          <button top="25" left="0" width="17" height="17" layout="topleft" follows="top" name="expand_btn" mouse_opaque="true"
+          <button bottom="-16" right="15" width="17" height="17" layout="topleft" follows="bottom" name="expand_btn" mouse_opaque="true"
             tab_stop="false" image_unselected="Notification_Expand" image_selected="Notification_Expand" />
         </panel>
       </layout_panel>
       </layout_stack>
-   </panel>
+    </panel>
   </layout_panel>
   <layout_panel top="0" left="0" height="196" follows="left|top|right|bottom" layout="topleft" name="layout_panel_expanded_view" visible="true">
-   <panel border="true" top="0" left="5" height="193" bevel_style="none" follows="left|top|right|bottom" layout="topleft" name="panel_expanded_view">
-      <layout_stack top="0" left="0" width="325" height="193" orientation="horizontal" follows="left|top|right|bottom" name="horizontal_stack">
+    <panel border="true" top="0" left="5" height="196" bevel_style="none" follows="left|top|right|bottom" layout="topleft" name="panel_expanded_view">
+      <layout_stack top="0" left="0" width="325" height="196" orientation="horizontal" follows="left|top|right|bottom" name="horizontal_stack">
       <layout_panel width="30" height="170" orientation="horizontal" follows="left|top|bottom" name="layout_panel_right_exp">
         <group_icon left="5" top="6" width="25" height="25" mouse_opaque="true" name="group_icon_exp" tool_tip="Group" default_icon_name="Generic_Group" visible="true"/>
         <avatar_icon left="5" top="6" width="25" height="25" mouse_opaque="true" name="avatar_icon_exp" tool_tip="Avatar" default_icon_name="Generic_Person" visible="false"/>
         <icon left="5" top="6" width="25" height="25" mouse_opaque="true" name="system_notification_icon_exp" tool_tip="Icon" image_name="System_Notification" visible="false"/>
+        <icon left="12" top="144" width="20" height="20" name="attachment_icon_exp" tool_tip="Attachment" image_name="Icon_Attachment_Large" follows="left" mouse_opaque="true" visible="false"/>
       </layout_panel>
-      <layout_panel width="230" height="170" orientation="horizontal" follows="left|top|right|bottom" name="layout_panel_middle_exp">
-        <panel border="false" top="0" width="230" height="38" bevel_style="none" follows="left|top|right|bottom" layout="topleft" name="main_info_panel_expanded">
+      <layout_panel width="230" height="196" orientation="horizontal" follows="left|top|right|bottom" name="layout_panel_middle_exp">
+        <panel border="false" top="0" width="230" height="196" bevel_style="none" follows="left|top|right|bottom" layout="topleft" name="main_info_panel_expanded">
+          <layout_stack top="0" left="0" width="230" height="196" orientation="vertical" follows="left|top|right|bottom" name="main_info_panel_vertical_stack">
+          <layout_panel top="0" left="0" width="230" height="30" layout="topleft" follows="left|top|right|bottom" name="notification_title_layout_panel" visible="true">
           <panel border="false" top="0" left="0" width="230" height="30" bevel_style="none" follows="left|top|right" layout="topleft" name="notification_title_panel_exp">
             <text allow_scroll="false" font="SansSerif" top="6" left="0" width="233" height="10" layout="topleft" follows="right|left" text_color="White"
               use_ellipses="true" word_wrap="false" mouse_opaque="false" name="notification_title_exp">
@@ -93,32 +105,41 @@
           </panel>
           <panel border="false" left="0" width="230" height="12" bevel_style="none" follows="left|top|right" layout="topleft" name="sender_time_panel_exp">
             <text allow_scroll="false" font="SansSerifSmall" top="0" left="0" width="145" height="13" layout="topleft" follows="right|left"
-              use_ellipses="true" word_wrap="false" mouse_opaque="false" name="sender_resident_exp" visible="false">
+              use_ellipses="true" word_wrap="false" mouse_opaque="false" name="sender_or_fee_box_exp" visible="false">
               Sender: "Resident R e s i d e n t R e s i d e n t"
             </text>
             <text allow_scroll="false" font="SansSerifSmall" top="0" right="-1" width="95" height="13" follows="right" halign="right" layout="topleft" left_pad="5"
               name="notification_time_exp" value="2014/12/24 23:30" />
           </panel>
-          <panel border="true" left="1" width="230" height="115" bevel_style="none" follows="left|top|right|bottom" layout="topleft" name="full_notice_text_panel_exp" visible="true"
+          <panel border="true" left="1" height="115" width="230" bevel_style="none" follows="left|top|right" layout="topleft" name="notification_text_panel_exp" visible="true"
+                   bg_visible="true">
+            <text allow_scroll="false" font="SansSerifSmall" top="4" left="5" width="220" height="70" layout="topleft" follows="left|top|right|bottom"
+                  use_ellipses="true" word_wrap="true" mouse_opaque="false" max_length="370" name="notification_text_exp" >
+                  Notice text goes here b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla. bla bla bla bla bla bla bla bla bla bla bla bla bla .
+            </text>
+          </panel>
+          <panel border="true" left="1" bottom="-5" width="230" height="22" bevel_style="none" follows="left|right|bottom" layout="topleft" name="attachment_panel" visible="false"
                    bg_visible="true">
-            <text allow_scroll="false" font="SansSerifSmall" top="4" left="5" width="220" height="80" layout="topleft" follows="left|top|right|bottom"
-              use_ellipses="true" word_wrap="true" mouse_opaque="false" max_length="400" name="notification_text_exp" >
-              Notice text goes here b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla. bla bla bla bla bla bla bla bla bla bla bla bla bla .
+            <text allow_scroll="false" font="SansSerifSmall" top="4" left="5" width="220" height="12" layout="topleft" follows="left|top|right|bottom"
+                  use_ellipses="true" word_wrap="true" mouse_opaque="false" max_length="96" name="attachment_text">
+                  Attachment goes here b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a b l a bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla. bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla .
             </text>
           </panel>
+          </layout_panel>
+          </layout_stack>
         </panel>
       </layout_panel>
       <layout_panel width="18" orientation="horizontal" follows="right|top|bottom" name="layout_panel_left_exp">
         <panel top="0" left="0" width="17" follows="left|top|right|bottom" layout="topleft" name="close_expand_panel_exp">
-          <button top="0" left="1" width="17" height="17" layout="topleft" follows="top" name="close_expanded_btn" mouse_opaque="true"
+          <button top="0" left="2" width="17" height="17" layout="topleft" follows="top" name="close_expanded_btn" mouse_opaque="true"
             tab_stop="false" image_unselected="Icon_Close_Foreground" image_selected="Icon_Close_Press" />
-          <button top="175" left="0" width="17" height="17" layout="topleft" follows="top" name="condense_btn" mouse_opaque="true"
+          <button bottom="5" left="0" width="17" height="17" layout="topleft" follows="bottom" name="condense_btn" mouse_opaque="true"
             tab_stop="false" image_unselected="Notification_Condense" image_selected="Notification_Condense" />
         </panel>
       </layout_panel>
-    </layout_stack>
+      </layout_stack>
+    </panel>
+  </layout_panel>
+  </layout_stack>
   </panel>
- </layout_panel>
-</layout_stack>
-</panel>
 </panel>
-- 
GitLab