Changes for page Message Sender Macro

Last modified by Ludovic Dubost on 2024/07/22 15:51

From version 4.1
edited by Ludovic Dubost
on 2017/01/07 20:21
Change comment: Install extension [org.xwiki.platform:xwiki-platform-messagestream-ui-8.4.3]
To version 10.1
edited by Ludovic Dubost
on 2020/12/03 18:41
Change comment: Install extension [org.xwiki.platform:xwiki-platform-messagestream-ui/12.8]

Summary

Details

XWiki.JavaScriptExtension[0]
Code
... ... @@ -1,78 +5,44 @@
1 -#set ($userSuggestScope = 'local')
2 -#if ($services.wiki.user && $services.wiki.user.userScope != "LOCAL_ONLY")
3 - #set ($userSuggestScope = 'global')
4 -#end
5 5  var XWiki = (function (XWiki) {
6 6  // Start XWiki augmentation.
7 -/**
8 - * Extends the UserPicker in order to display the selected user/group inline after the target text input.
9 - */
10 -var CustomUserPicker = Class.create(XWiki.widgets.UserPicker, {
11 - // @Override
12 - _createSelectionManager: function($super, options) {
13 - var selectionManager = $super(Object.extend(options, {
14 - listInsertionPosition : 'after',
15 - acceptFreeText : false
16 - }));
17 - // Overwrite the way the selected item is displayed.
18 - selectionManager.displayItem = function(suggestion) {
19 - var targetInfo = new Element('span').update(suggestion.info).insert(this.createDeleteTool());
20 - var targetClass = this.suggest.sources[0].script.indexOf('uorg=group') > 0 ? 'target-group' : 'target-user';
21 - return new Element('li', {'class': targetClass}).insert(targetInfo).insert(this.createItemInput(suggestion));
22 - }.bind(selectionManager);
23 - return selectionManager;
24 - }
25 -});
26 -
27 27  XWiki.MessageStream = Class.create({
28 - targetsWithName : ['user', 'group'],
29 - suggestParameters : {
30 - user : {
31 - script: '$doc.getURL("get", "xpage=uorgsuggest&uorg=user&wiki=${userSuggestScope}")&',
32 - noresults: "$escapetool.javascript($services.localization.render('core.widgets.userPicker.noResults'))"
33 - },
34 - group : {
35 - script: "$doc.getURL('get', 'xpage=uorgsuggest&uorg=group')&",
36 - noresults: "$escapetool.javascript($services.localization.render('core.widgets.groupPicker.noResults'))"
37 - }
4 + initialize : function(container) {
5 + container = container || $(document.body);
6 + this.prepareForms(container);
7 + this.enhanceSelect(container);
38 38   },
39 - initialize : function() {
40 - this.prepareForms();
41 - this.enhanceSelect();
42 - },
43 43   prepareTargetInput : function(event, element) {
44 44   var targetType = element.options[element.selectedIndex].value;
45 45   element.className = targetType;
46 - if (!element.__targetNameInput) {return;}
47 - if (this.targetsWithName.indexOf(targetType) < 0) {
48 - element.__targetNameInput.addClassName('hidden');
49 - if (element.__targetNameInput.__x_suggest) {
50 - element.__targetNameInput.__x_suggest.detach();
51 - }
52 - } else {
53 - // Focus the text input so that the place-holder value is cleared if present. Otherwise the user picker will treat
54 - // the place-holder value as if it was typed by the user and will automatically select the corresponding suggestion.
55 - element.__targetNameInput.removeClassName('hidden').activate();
56 - // Defer the creation of the user picker to allow the focus listeners to be called first (in order to clear the
57 - // place-holder value).
58 - this.suggestParameters[targetType] && function() {
59 - new CustomUserPicker(element.__targetNameInput, this.suggestParameters[targetType]);
60 - }.bind(this).defer();
12 + var messageStream = element.up('.messagestream');
13 + var targetInputContainer = messageStream.down('.message-target-' + targetType);
14 + if (!targetInputContainer) {
15 + targetInputContainer = messageStream.down('.message-target-default');
61 61   }
62 - },
63 - enhanceSelect: function () {
64 - $$('.messagestream select[name="visibilityLevel"]').each(function(element) {
65 - element.addClassName(element.options[element.selectedIndex].value);
66 - element.__targetNameInput = element.up('.messagestream').down('input[name="targetName"]');
67 - if (element.__targetNameInput && this.targetsWithName.indexOf(element.options[element.selectedIndex].value) < 0) {
68 - element.__targetNameInput.addClassName('hidden');
17 + messageStream.select('.message-target').forEach(function(messageTargetContainer) {
18 + var fields = messageTargetContainer.select('input, select, textarea');
19 + if (messageTargetContainer === targetInputContainer) {
20 + messageTargetContainer.removeClassName('hidden');
21 + fields.forEach(function(field) {
22 + field.enable();
23 + field.hasClassName('selectized') && field.selectize.enable();
24 + });
25 + } else {
26 + messageTargetContainer.addClassName('hidden');
27 + fields.forEach(function(field) {
28 + field.disable();
29 + field.hasClassName('selectized') && field.selectize.disable();
30 + });
69 69   }
32 + });
33 + },
34 + enhanceSelect: function (container) {
35 + container.select('.messagestream select[name="visibilityLevel"]').each(function(element) {
70 70   element.observe('change', this.prepareTargetInput.bindAsEventListener(this, element));
71 71   this.prepareTargetInput(null, element);
72 72   }.bind(this));
73 73   },
74 - prepareForms: function() {
75 - $$('.messagestream form').each(function(msForm) {
40 + prepareForms: function(container) {
41 + container.select('.messagestream form').each(function(msForm) {
76 76   msForm.action = msForm.action.replace(/xredirect=.*$/, 'xpage=plain')
77 77   msForm.observe('submit', function(event) {
78 78   event.stop();
... ... @@ -128,11 +128,21 @@
128 128   }
129 129  });
130 130  
131 -var init = function() {
132 - return new XWiki.MessageStream();
97 +var init = function (event) {
98 + var elements = (event && event.memo.elements) || [$(document.body)];
99 + elements.forEach(function(container) {
100 + new XWiki.MessageStream(container);
101 + });
102 + return true;
133 133  };
134 -(XWiki.domIsLoaded && init()) || document.observe('xwiki:dom:loaded', init);
135 135  
105 +// Initialize the message sender macro when the page is loaded.
106 +(XWiki.domIsLoaded && init())
107 +|| document.observe('xwiki:dom:loaded', init);
108 +
109 +// Initialize the message sender macro when it is added after the page is loaded.
110 +document.observe('xwiki:dom:updated', init);
111 +
136 136  // End XWiki augmentation.
137 137  return XWiki;
138 138  }(XWiki || {}));
XWiki.StyleSheetExtension[0]
Code
... ... @@ -1,29 +1,48 @@
1 1  #template('colorThemeInit.vm')
2 2  
3 3  .messagestream-tools {
4 + display: flex;
4 4   position: relative;
5 5   margin: .5em 0 1em;
6 6  }
7 -.messagestream-tools .accepted-suggestions {
8 - display: inline;
8 +.messagestream select {
9 + width: auto;
9 9  }
10 -.messagestream-tools .accepted-suggestions .target-user,
11 -.messagestream-tools .accepted-suggestions .target-group {
12 - background: none no-repeat scroll left center transparent;
13 - display: inline-block;
14 - margin-right: 1em;
15 - padding: 0 1px 0 18px;
11 +.messagestream .message-target {
12 + flex-grow: 1;
13 + margin-left: .3em;
16 16  }
17 -.messagestream-tools .accepted-suggestions .target-user {
18 - background-image: url("$xwiki.getSkinFile('icons/silk/user.png')");
15 +
16 +.messagestream .message-content {
17 + padding: .5em 0 .5em 75px;
19 19  }
20 -.messagestream-tools .accepted-suggestions .target-group {
21 - background-image: url("$xwiki.getSkinFile('icons/silk/group.png')");
19 +
20 +.messagestream .activitySnapshot {
21 + height: 30px;
22 + margin: 5px 0 0 -50px;
23 + position: absolute;
22 22  }
23 -.messagestream select {
24 - width: auto;
25 +
26 +.messagestream .activitySnapshot img {
27 + border-radius: 10px 10px 0 10px;
28 + box-shadow: -1px 1px 1px rgba(128,128,128,0.6);
25 25  }
26 -.messagestream input.targetName {
27 - margin-right: .3em;
28 - width: auto;
30 +
31 +/* User's avatar */
32 +.messagestream .activitySnapshot .avatar {
33 + border-radius: 4px;
34 + box-shadow: 0 0 2px 1px rgba(128,128,128,0.6);
29 29  }
36 +
37 +.messagestream .activitySnapshot .activityActionAvatar {
38 + background: $theme.pageContentBackgroundColor;
39 + border-color: $theme.pageContentBackgroundColor;
40 + border-style: solid;
41 + border-width: 4px 1px 1px 3px;
42 + box-sizing: content-box;
43 + bottom: -5px;
44 + height: 16px;
45 + position: absolute;
46 + right: -10px;
47 + width: 16px;
48 +}
XWiki.WikiMacroClass[0]
Macro code
... ... @@ -7,8 +7,6 @@
7 7  #set ($configClass = $xwiki.getDocument($config).getxWikiClass())
8 8  #set ($isMessageStreamActive = $services.messageStream.isActive())
9 9  
10 -#set ($currentUser = $services.model.serialize($xcontext.userReference, 'default'))
11 -
12 12  #set ($activityActionsMap = {
13 13   'publicMessage': 'icons/silk/user_comment.png',
14 14   'personalMessage': 'icons/silk/user_comment.png',
... ... @@ -34,9 +34,6 @@
34 34  ##
35 35  ## Skin Extensions
36 36  ##--------------------------------------------------------------
37 -#set ($discard = $xwiki.jsfx.use('uicomponents/suggest/suggestPicker.js'))
38 -#set ($discard = $xwiki.jsfx.use('uicomponents/widgets/userpicker/userPicker.js'))
39 -#set ($discard = $xwiki.ssx.use('Main.Activity'))
40 40  #set ($discard = $xwiki.ssx.use('Main.MessageSenderMacro'))
41 41  #set ($discard = $xwiki.jsx.use('Main.MessageSenderMacro'))
42 42  {{/velocity}}
... ... @@ -115,11 +115,11 @@
115 115   #set ($actionQueryString = "xredirect=$escapetool.url($xredirect)")
116 116   {{html}}
117 117   ## Wrap the form in a div so that the layout is preserved in inline mode (where the form is stripped by the rendering).
118 - <div class='messagestream activityUser xform'>
113 + <div class='messagestream xform'>
119 119   #if (!$inEditMode)
120 120   <form action="${xwiki.getURL('Main.MessageSenderMacro', 'view', $!{actionQueryString})}" method='post'>
121 121   #end
122 - <div class='activityContent'>
117 + <div class='message-content'>
123 123   #if(!$inEditMode)
124 124   ## CSRF prevention
125 125   <input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" />
... ... @@ -141,13 +141,13 @@
141 141   #if (!$defaultTarget)
142 142   #if ($doc.getObject('XWiki.XWikiGroups'))
143 143   #set ($defaultTarget = 'group')
144 - #set ($targetName = $doc.prefixedFullName)
139 + #set ($targetName = $doc.fullName)
145 145   #elseif ($doc.getObject('XWiki.XWikiUsers'))
146 - #if ($doc.prefixedFullName == $currentUser)
141 + #if ($doc.documentReference == $xcontext.userReference)
147 147   #set ($defaultTarget = 'followers')
148 148   #else
149 149   #set ($defaultTarget = 'user')
150 - #set ($targetName = $doc.prefixedFullName)
145 + #set ($targetName = $doc.fullName)
151 151   #end
152 152   #else
153 153   #set ($defaultTarget = 'everyone')
... ... @@ -160,16 +160,31 @@
160 160   #end
161 161   </select>
162 162   </label>
163 - <label for="targetName$!{targetNameCounter}">
164 - <span class='hidden'>Name:</span>
165 - <input type="text" name="targetName" id="targetName$!targetNameCounter" class="targetName withTip useTitleAsTip" value="$!targetName" size="15"
166 - title="$services.localization.render('xe.activity.messages.visibility.targetName.tip')" #if ($inEditMode) disabled="disabled"#end/>
167 - </label>
168 - #if (!$targetNameCounter)
169 - #set ($targetNameCounter = 1)
170 - #else
171 - #set ($targetNameCounter = $targetNameCounter + 1)
158 + #set ($suggestPickerParams = {
159 + 'name': 'targetName',
160 + 'title': $services.localization.render('xe.activity.messages.visibility.targetName.tip')
161 + })
162 + #foreach ($target in ['user', 'group'])
163 + #if ($possibleTargets.contains($target))
164 + #set ($notDefaultTarget = $target != $defaultTarget)
165 + <div class="message-target message-target-$target#if ($notDefaultTarget) hidden#end">
166 + #set ($discard = $suggestPickerParams.put('class', 'targetName'))
167 + #set ($suggestPickerParams.disabled = $inEditMode || $notDefaultTarget)
168 + #set ($suggestPickerParams.value = $targetName)
169 + #if ($notDefaultTarget)
170 + #set ($suggestPickerParams.value = '')
171 + #end
172 + #if ($target == 'user')
173 + #userPicker(false, $suggestPickerParams)
174 + #else
175 + #groupPicker(false, $suggestPickerParams)
176 + #end
177 + </div>
178 + #end
172 172   #end
180 + <div class="message-target message-target-default">
181 + <input type="hidden" name="targetName" value="$!escapetool.xml($targetName)" class="targetName" />
182 + </div>
173 173   </div>
174 174   <div class='messagestream-buttons'>
175 175   <span class='butonwrapper'><input type='submit' value="$services.localization.render('xe.activity.messages.submit')" class='button'#if($inEditMode) disabled='disabled'#end/></span>