Index: trunk/extensions/MoodBar/SpecialFeedbackDashboard.php |
— | — | @@ -131,7 +131,7 @@ |
132 | 132 | * @return string HTML |
133 | 133 | */ |
134 | 134 | public static function formatListItem( $row, $params = array() ) { |
135 | | - global $wgLang; |
| 135 | + global $wgLang, $wgUser; |
136 | 136 | |
137 | 137 | $classes = array('fbd-item'); |
138 | 138 | $toolLinks = array(); |
— | — | @@ -194,12 +194,28 @@ |
195 | 195 | $toolLinks[] = self::getHiddenFooter($feedbackItem, 'hidden'); |
196 | 196 | } |
197 | 197 | } |
| 198 | + |
198 | 199 | } elseif ( in_array('admin', $params) ) { |
199 | 200 | $toolLinks[] = self::getHideLink( $feedbackItem ); |
| 201 | + |
200 | 202 | } |
201 | 203 | |
| 204 | + //only show response elements if feedback is not hidden, and user is logged in |
| 205 | + if ($feedbackItem->getProperty('hidden-state') == false |
| 206 | + && !$wgUser->isAnon() ) { |
| 207 | + $respondToThis = wfMessage('moodbar-respond-collapsed').' '.wfMessage("moodbar-respond-text"); |
| 208 | + $responseElements = <<<HTML |
| 209 | + <div class="fbd-item-response"> |
| 210 | + <a class="fbd-respond-link">$respondToThis</a> |
| 211 | + </div> |
| 212 | +HTML; |
| 213 | + } |
| 214 | + |
202 | 215 | $classes = Sanitizer::encodeAttribute( implode(' ', $classes) ); |
203 | 216 | $toolLinks = implode("\n", $toolLinks ); |
| 217 | + if (!$responseElements) { |
| 218 | + $responseElements = ""; |
| 219 | + } |
204 | 220 | |
205 | 221 | return <<<HTML |
206 | 222 | <li class="$classes" data-mbccontinue="$continueData"> |
— | — | @@ -207,9 +223,10 @@ |
208 | 224 | <span class="fbd-item-emoticon-label">$typeMsg</span> |
209 | 225 | </div> |
210 | 226 | <div class="fbd-item-time">$timeMsg</div> |
211 | | -$userInfo |
| 227 | + $userInfo |
212 | 228 | <div class="fbd-item-message" dir="auto">$comment</div> |
213 | | -$toolLinks |
| 229 | + $toolLinks |
| 230 | + $responseElements |
214 | 231 | <div style="clear:both"></div> |
215 | 232 | </li> |
216 | 233 | HTML; |
Index: trunk/extensions/MoodBar/MoodBar.i18n.php |
— | — | @@ -34,6 +34,12 @@ |
35 | 35 | 'moodbar-what-label' => 'What is this?', |
36 | 36 | 'moodbar-what-collapsed' => '▶', // Optional, only change e.g. for RTL languages. ▶ |
37 | 37 | 'moodbar-what-expanded' => '▼', // Ignore, do not translate. ▼ |
| 38 | + 'moodbar-respond-collapsed' => '▶', // Optional, only change e.g. for RTL languages. ▶ |
| 39 | + 'moodbar-respond-expanded' => '▼', // Ignore, do not translate. ▼ |
| 40 | + 'moodbar-respond-text' => 'Respond to this', |
| 41 | + 'moodbar-response-add' => 'Add a response', |
| 42 | + 'moodbar-response-nosig' => 'signature not required', |
| 43 | + 'moodbar-response-btn' => 'Send Response', |
38 | 44 | 'moodbar-what-content' => 'This feature is designed to help the community understand the experience of people editing the site. |
39 | 45 | For more information, please visit the $1.', |
40 | 46 | 'moodbar-what-link' => 'feature page', |
— | — | @@ -97,6 +103,8 @@ |
98 | 104 | 'moodbar-comment-hidden' => '(Feedback hidden by administrative action)', |
99 | 105 | 'moodbar-feedback-show' => 'show hidden feedback', |
100 | 106 | 'moodbar-feedback-hide' => 'hide feedback', |
| 107 | + 'moodbar-feedback-action-confirm' => 'Confirm', |
| 108 | + 'moodbar-feedback-action-cancel' => 'Cancel', |
101 | 109 | 'moodbar-hidden-footer' => 'Hidden feedback by $1 on $2 $3, reason: $4 $5', |
102 | 110 | 'moodbar-hidden-footer-without-log' => 'Hidden feedback $1', |
103 | 111 | 'moodbar-feedback-restore' => 'restore hidden feedback', |
— | — | @@ -122,92 +130,18 @@ |
123 | 131 | 'moodbar-log-header' => 'This is the log of actions taken on feedback items listed on the [[Special:FeedbackDashboard|feedback dashboard]].', |
124 | 132 | 'moodbar-log-hide' => 'hid [[$1]]', |
125 | 133 | 'moodbar-log-restore' => 'restored the visibility for [[$1]]', |
| 134 | + //Feedback Response |
| 135 | + 'moodbar-response-ula' => 'By clicking the "$1" button, you aggree to the $2, and you irrevocably agree to release your contribution under the under the $3 License and the $4. |
| 136 | +You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.', |
| 137 | + 'moodbar-response-terms-of-use' => 'Terms Of Use', |
| 138 | + 'moodbar-response-terms-of-use-link' => '#', |
| 139 | + 'moodbar-response-cc' => 'Creative Commons', |
| 140 | + 'moodbar-response-cc-link' => 'http://creativecommons.org/licenses/by-sa/3.0/us/legalcode', |
| 141 | + 'moodbar-response-gfdl' => 'GFDL', |
| 142 | + 'moodbar-response-gfdl-link' => 'http://www.gnu.org/copyleft/fdl.html', |
| 143 | + 'feedbackresponse-success' => 'Thank you. Your response was added to the User\'s Talk page.', |
126 | 144 | ); |
127 | | - |
128 | | -/** Message documentation (Message documentation) |
129 | | - * @author Krinkle |
130 | | - * @author SPQRobin |
131 | | - * @author EugeneZelenko |
132 | | - * @author Lloffiwr |
133 | | - * @author Purodha |
134 | | - * @author Raymond |
135 | | - */ |
136 | 145 | |
137 | | -$messages['qqq'] = array( |
138 | | - 'moodbar-desc' => 'This is a feature in development. See [[mw:MoodBar 0.1/Design]] for background information.', |
139 | | - 'moodbar-trigger-editing' => "Link text of the MoodBar overlay trigger. \$1 is the SITENAME. The implied sentence is ''\"Using [Sitename] made me happy/sad/...\"''. See [[mw:MoodBar 0.1/Design]] for background development information.", |
140 | | - 'moodbar-trigger-feedback' => 'Link text of the MoodBar overlay trigger. $1 is the SITENAME.', |
141 | | - 'moodbar-intro-editing' => 'Intro title of the MoodBar overlay trigger. $1 is the SITENAME.', |
142 | | - 'moodbar-intro-feedback' => 'Intro title of the MoodBar overlay trigger. $1 is the SITENAME.', |
143 | | - 'moodbar-close' => 'Link text of the close-button. Make sure to include parentheses. |
144 | | - |
145 | | -See also: |
146 | | -* {{msg|parentheses}}', |
147 | | - 'tooltip-moodbar-what' => 'Tooltip displayed when hovering the What-link. |
148 | | - |
149 | | -See also: |
150 | | -* {{msg|moodbar-what-label}}', |
151 | | - 'moodbar-what-target' => 'Complete URL (including http://) or article name where more info can be found.', |
152 | | - 'moodbar-what-label' => 'Link text for the page where more info abut MoodBar can be found.', |
153 | | - 'moodbar-form-policy-text' => 'Text displayed below the input area. |
154 | | - |
155 | | -See also: |
156 | | -* {{msg|moodbar-form-policy-label}}', |
157 | | - 'moodbar-form-policy-label' => 'Label text for the link to the privacy policy,. |
158 | | - |
159 | | -See also: |
160 | | -* {{msg|moodbar-form-policy-text}}', |
161 | | - 'moodbar-loading-title' => 'Title of the screen when the widget is loading.', |
162 | | - 'moodbar-success-title' => 'Title of the screen after the feedback was successfully submitted.', |
163 | | - 'moodbar-error-title' => 'Title of the screen when after an error occurred and submission aborted.', |
164 | | - 'moodbar-loading-subtitle' => 'Subtitle of Loading-screen. $1 is the SITENAME', |
165 | | - 'moodbar-success-subtitle' => 'Subtitle of screen when feedback was successfullyully submitted. $1 is the SITENAME', |
166 | | - 'moodbar-error-subtitle' => 'Subtitle of screen when an error occurred. $1 is the SITENAME', |
167 | | - 'moodbar-feedback-more' => 'Text of the link that the user can click to see more results. Only visible if JavaScript is enabled.', |
168 | | - 'moodbar-feedback-newer' => 'Text of the link that the user can click to go back to more recent results. Only visible if JavaScript is not enabled.', |
169 | | - 'moodbar-feedback-older' => 'Text of the link that the user can click to see less recent results. Only visible if JavaScript is not enabled.', |
170 | | - 'moodbar-desc' => '{{desc}} |
171 | | -This is a feature in development. See [[mw:MoodBar 0.1/Design]] for background information.', |
172 | | - 'moodbar-trigger-feedback' => 'Link text of the MoodBar overlay trigger. $1 is the SITENAME.', |
173 | | - 'moodbar-trigger-editing' => "Link text of the MoodBar overlay trigger. \$1 is the SITENAME. The implied sentence is ''\"Using [Sitename] made me happy/sad/...\"''. See [[mw:MoodBar 0.1/Design]] for background development information.", |
174 | | - 'moodbar-close' => 'Link text of the close-button. Make sure to include parentheses. |
175 | | - |
176 | | -See also: |
177 | | -* {{msg|parentheses}} |
178 | | -{{Identical|Close}}', |
179 | | - 'moodbar-intro-feedback' => 'Intro title of the MoodBar overlay trigger. $1 is the SITENAME.', |
180 | | - 'moodbar-intro-editing' => '[[File:MoodBar-Step-1.png|right|200px]] |
181 | | -Intro title of the MoodBar overlay trigger. $1 is the SITENAME.', |
182 | | - 'moodbar-type-happy-title' => 'No gender support ([[bugzilla:30071|bug 30071]])', |
183 | | - 'moodbar-type-sad-title' => 'No gender support ([[bugzilla:30071|bug 30071]])', |
184 | | - 'moodbar-type-confused-title' => 'No gender support ([[bugzilla:30071|bug 30071]])', |
185 | | - 'tooltip-moodbar-what' => 'Tooltip displayed when hovering the What-link. |
186 | | - |
187 | | -See also: |
188 | | -* {{msg|moodbar-what-label}}', |
189 | | - 'moodbar-what-label' => 'Link text for the page where more info abut MoodBar can be found. |
190 | | -{{Identical|What is this}}', |
191 | | - 'moodbar-what-content' => '$1 is the message {{msg-mw|moodbar-what-link}} which links to the page [[mw:MoodBar|MoodBar]] on MediaWiki.org.', |
192 | | - 'moodbar-what-link' => 'This is the link embedded as parameter $1 in {{msg-mw|moodbar-what-content}}.', |
193 | | - 'moodbar-privacy' => 'Parameters: |
194 | | -*$1 - a link having the anchor text {{msg-mw|moodbar-privacy-link}} |
195 | | - |
196 | | -The link is to the privacy policy of the wiki. |
197 | | - |
198 | | -See [[Thread:Support/About MediaWiki:Moodbar-privacy/en (2)/reply (4)|discussion]].', |
199 | | - 'moodbar-privacy-link' => 'This is the anchor text being used in the link replacing $1 in the message {{msg-mw|moodbar-privacy}}', |
200 | | - 'moodbar-header-timestamp' => '{{Identical|Timestamp}}', |
201 | | - 'moodbar-header-type' => '{{Identical|Type}}', |
202 | | - 'moodbar-header-page' => '{{Identical|Page}}', |
203 | | - 'moodbar-header-user' => '{{Identical|User}}', |
204 | | - 'moodbar-header-comment' => '{{Identical|Comment}}', |
205 | | - 'moodbar-header-namespace' => '{{Identical|Namespace}}', |
206 | | - 'moodbar-type-happy' => '$1 is the username that can be used for GENDER', |
207 | | - 'moodbar-type-sad' => '$1 is the username that can be used for GENDER', |
208 | | - 'moodbar-type-confused' => '$1 is the username that can be used for GENDER', |
209 | | - 'moodbar-user-ip' => '{{Identical|IP Address}}', |
210 | | -); |
211 | | - |
212 | 146 | /** Message documentation (Message documentation) |
213 | 147 | * @author EugeneZelenko |
214 | 148 | * @author IAlex |
— | — | @@ -294,6 +228,29 @@ |
295 | 229 | 'moodbar-feedback-response-title' => 'The title for appending feedback response text to a user talk page', |
296 | 230 | 'moodbar-feedback-view-link' => 'link to an individual feedback', |
297 | 231 | 'moodbar-user-ip' => '{{Identical|IP Address}}', |
| 232 | +//Feedback Response |
| 233 | + 'moodbar-response-ula' => "Text of the user license agreement. |
| 234 | + * $1 {{mw-msg|moodbar-response-btn}} |
| 235 | + * $2 {{mw-msg|moodbar-response-terms-of-use}} |
| 236 | + * $3 {{mw-msg|moodbar-response-cc}} |
| 237 | + * $4 {{mw-msg|moodbar-response-gfdl}}", |
| 238 | + 'moodbar-response-terms-of-use'=> "Terms of Use Text", |
| 239 | + 'moodbar-response-terms-of-use-link' => "Terms of Use Link", |
| 240 | + 'moodbar-response-cc' => 'Creative Commons Text', |
| 241 | + 'moodbar-response-cc-link' => 'Hyperlink to Creative Commons License', |
| 242 | + 'moodbar-response-gfdl' => 'GFDL Text', |
| 243 | + 'moodbar-response-gfdl-link' => 'GFDL Hyperlink', |
| 244 | + 'feedbackresponse-success' => 'Text for successful feedback response', |
| 245 | + 'moodbar-action-reason' => 'Text for Admin action reason', |
| 246 | + 'moodbar-action-reason-required' => 'Text explaining admin action reason is required', |
| 247 | + 'moodbar-feedback-action-confirm' => 'Text for admin action confirm button', |
| 248 | + 'moodbar-feedback-action-cancel' => 'Text for admin action cancel button', |
| 249 | + 'moodbar-respond-text' => 'Text for Response toggle', |
| 250 | + 'moodbar-respond-collapsed' => 'Special character for response form collapsed', |
| 251 | + 'moodbar-respond-expanded' => 'Special character for response form expanded', |
| 252 | + 'moodbar-response-add' => 'Text for Response heading', |
| 253 | + 'moodbar-response-nosig' => 'Text explaining signature is not required', |
| 254 | + 'moodbar-response-btn' => 'Text for Response button', |
298 | 255 | ); |
299 | 256 | |
300 | 257 | /** Afrikaans (Afrikaans) |
Index: trunk/extensions/MoodBar/modules/ext.moodBar/ext.moodBar.core.css |
— | — | @@ -149,7 +149,7 @@ |
150 | 150 | /* @embed */ |
151 | 151 | background-image: url(images/type-happy-dull.png); |
152 | 152 | } |
153 | | -.mw-moodBar-types-select .mw-moodBar-type-happy.mw-moodBar-selected { |
| 153 | +.mw-moodBar-types-select .mw-moodBar-type-happy.mw-moodBar-happy-selected { |
154 | 154 | /* @embed */ |
155 | 155 | background-image: url(images/type-happy-selected.png); |
156 | 156 | } |
— | — | @@ -171,7 +171,7 @@ |
172 | 172 | /* @embed */ |
173 | 173 | background-image: url(images/type-sad-dull.png); |
174 | 174 | } |
175 | | -.mw-moodBar-types-select .mw-moodBar-type-sad.mw-moodBar-selected { |
| 175 | +.mw-moodBar-types-select .mw-moodBar-type-sad.mw-moodBar-sad-selected { |
176 | 176 | /* @embed */ |
177 | 177 | background-image: url(images/type-sad-selected.png); |
178 | 178 | } |
— | — | @@ -193,7 +193,7 @@ |
194 | 194 | /* @embed */ |
195 | 195 | background-image: url(images/type-confused-dull.png); |
196 | 196 | } |
197 | | -.mw-moodBar-types-select .mw-moodBar-type-confused.mw-moodBar-selected { |
| 197 | +.mw-moodBar-types-select .mw-moodBar-type-confused.mw-moodBar-confused-selected { |
198 | 198 | /* @embed */ |
199 | 199 | background-image: url(images/type-confused-selected.png); |
200 | 200 | } |
Index: trunk/extensions/MoodBar/modules/ext.moodBar/ext.moodBar.core.js |
— | — | @@ -114,11 +114,15 @@ |
115 | 115 | mb.ui.overlay.find( '.mw-moodBar-formInput' ).focus(); |
116 | 116 | $mwMoodBarTypes.addClass( 'mw-moodBar-types-select' ); |
117 | 117 | mb.feedbackItem.type = $el.attr( 'rel' ); |
118 | | - $el.addClass( 'mw-moodBar-selected' ); |
| 118 | + $el.addClass( 'mw-moodBar-selected' ) |
| 119 | + .addClass( 'mw-moodBar-' + mb.feedbackItem.type + '-selected' ); |
119 | 120 | $el.parent() |
120 | 121 | .find( '.mw-moodBar-selected' ) |
121 | 122 | .not( $el ) |
122 | | - .removeClass( 'mw-moodBar-selected' ); |
| 123 | + .removeClass( 'mw-moodBar-selected' ) |
| 124 | + .removeClass( 'mw-moodBar-happy-selected' ) |
| 125 | + .removeClass( 'mw-moodBar-sad-selected' ) |
| 126 | + .removeClass( 'mw-moodBar-confused-selected' ); |
123 | 127 | mb.validate(); |
124 | 128 | } ) |
125 | 129 | .get( 0 ) |
— | — | @@ -214,7 +218,7 @@ |
215 | 219 | var message, counterElement; |
216 | 220 | message = mw.msg( 'moodbar-form-note-dynamic' ); |
217 | 221 | counterElement = mw.html.element( 'span', { |
218 | | - 'id': 'mw-moodBar-charCount', |
| 222 | + 'id': 'mw-moodBar-charCount' |
219 | 223 | } ); |
220 | 224 | return mw.html.escape( message ) |
221 | 225 | .replace( /\$1/, counterElement ); |
Index: trunk/extensions/MoodBar/modules/ext.moodBar.dashboard/ext.moodBar.dashboard.css |
— | — | @@ -3,6 +3,7 @@ |
4 | 4 | #fbd-filters { |
5 | 5 | position: absolute; |
6 | 6 | width: 14em; |
| 7 | + left:0px; /* needed for ie6 & ie7 */ |
7 | 8 | } |
8 | 9 | |
9 | 10 | #fbd-filters form { |
— | — | @@ -46,12 +47,14 @@ |
47 | 48 | margin: 0; |
48 | 49 | padding: 0; |
49 | 50 | list-style: none; |
| 51 | + list-style-type:none; |
50 | 52 | } |
51 | 53 | |
52 | 54 | #fbd-filters-types li { |
53 | 55 | margin: 0 0 0 0.75em; |
54 | 56 | padding: 0; |
55 | 57 | list-style: none; |
| 58 | + list-style-image:none; /* ie 7 fix */ |
56 | 59 | } |
57 | 60 | |
58 | 61 | #fbd-filters-types label { |
— | — | @@ -83,9 +86,10 @@ |
84 | 87 | |
85 | 88 | #fbd-list { |
86 | 89 | margin: 0px 20px 0px 15em; |
87 | | - padding: 0; |
| 90 | + padding: 0px; |
88 | 91 | min-height: 20em; |
89 | 92 | list-style: none; |
| 93 | + list-style-image:none; /* ie 7 fix */ |
90 | 94 | } |
91 | 95 | |
92 | 96 | .client-nojs #fbd-list-more { |
— | — | @@ -173,7 +177,10 @@ |
174 | 178 | .fbd-item { |
175 | 179 | border-bottom: solid 1px silver; |
176 | 180 | position: relative; |
177 | | - margin-bottom:1em; |
| 181 | + margin-top:0.5em; |
| 182 | + margin-bottom:0.5em; |
| 183 | + |
| 184 | + padding:0; |
178 | 185 | } |
179 | 186 | |
180 | 187 | .fbd-item-emoticon { |
— | — | @@ -210,8 +217,8 @@ |
211 | 218 | padding: 0; |
212 | 219 | } |
213 | 220 | |
214 | | -.fbd-item-userLinks { |
215 | | - font-size: 1em; |
| 221 | +.fbd-item-userLinks{ |
| 222 | + font-size: 1em; |
216 | 223 | } |
217 | 224 | |
218 | 225 | .fbd-item-time { |
— | — | @@ -222,23 +229,50 @@ |
223 | 230 | .fbd-item-message { |
224 | 231 | font-size: 1.4em; |
225 | 232 | margin-top: 0.25em; |
| 233 | + margin-left:81px; |
| 234 | + min-height:40px; |
226 | 235 | } |
227 | 236 | |
228 | 237 | .fbd-item-permalink, |
229 | 238 | .fbd-item-show, |
230 | 239 | .fbd-item-hide, |
231 | | -.fbd-item-reason{ |
| 240 | +.fbd-item-reason { |
232 | 241 | float: right; |
233 | 242 | font-size: 0.8em; |
234 | 243 | margin-left: 0.2em; |
235 | 244 | margin-right: 0.2em; |
236 | 245 | } |
237 | | - |
| 246 | +.fbd-respond-link { |
| 247 | + font-size:1.1em; |
| 248 | + cursor:pointer; |
| 249 | + letter-spacing: -0.01em; |
| 250 | +} |
| 251 | +.fbd-respond-link:hover { |
| 252 | + text-decoration:none; |
| 253 | +} |
238 | 254 | .fbd-item-restore { |
239 | 255 | font-size: 0.8em; |
240 | 256 | color: silver; |
241 | 257 | } |
242 | | - |
243 | 258 | .fbd-hidden { |
244 | 259 | color: silver; |
245 | 260 | } |
| 261 | +.fbd-response-form { |
| 262 | + margin:0em 0px 1em 81px; |
| 263 | +} |
| 264 | +.fbd-response-form b { |
| 265 | + font-size:1em; |
| 266 | +} |
| 267 | +.fbd-response-form small{ |
| 268 | + font-size:0.8em; |
| 269 | + color:#262626; |
| 270 | +} |
| 271 | +.fbd-response-formNote { |
| 272 | + float:right; |
| 273 | +} |
| 274 | +.fbd-response-submit { |
| 275 | + float:right; |
| 276 | +} |
| 277 | +.center { |
| 278 | + text-align:center; |
| 279 | +} |
\ No newline at end of file |
Index: trunk/extensions/MoodBar/modules/ext.moodBar.dashboard/ext.moodBar.dashboard.js |
— | — | @@ -1,7 +1,7 @@ |
2 | 2 | /** |
3 | 3 | * AJAX code for Special:MoodBarFeedback |
4 | 4 | */ |
5 | | -jQuery( function( $ ) { |
| 5 | +jQuery(function( $ ) { |
6 | 6 | /** |
7 | 7 | * Saved form state |
8 | 8 | */ |
— | — | @@ -115,13 +115,13 @@ |
116 | 116 | 'mbclimit': limit + 2 // we drop the first and last result |
117 | 117 | }; |
118 | 118 | if ( mode == 'more' ) { |
119 | | - reqData['mbccontinue'] = $( '#fbd-list').find( 'li:last' ).data( 'mbccontinue' ); |
| 119 | + reqData.mbccontinue = $( '#fbd-list').find( 'li:last' ).data( 'mbccontinue' ); |
120 | 120 | } |
121 | 121 | if ( formState.types.length ) { |
122 | | - reqData['mbctype'] = formState.types.join( '|' ); |
| 122 | + reqData.mbctype = formState.types.join( '|' ); |
123 | 123 | } |
124 | 124 | if ( formState.username.length ) { |
125 | | - reqData['mbcuser'] = formState.username; |
| 125 | + reqData.mbcuser = formState.username; |
126 | 126 | } |
127 | 127 | |
128 | 128 | $.ajax( { |
— | — | @@ -144,7 +144,7 @@ |
145 | 145 | $ul = $( '#fbd-list' ), |
146 | 146 | moreResults = false, |
147 | 147 | i; |
148 | | - if ( len == 0 ) { |
| 148 | + if ( len === 0 ) { |
149 | 149 | if ( mode == 'more' ) { |
150 | 150 | showMessage( mw.msg( 'moodbar-feedback-nomore' ) ); |
151 | 151 | } else { |
— | — | @@ -249,16 +249,19 @@ |
250 | 250 | } |
251 | 251 | |
252 | 252 | /** |
253 | | - * Do this before administrative action to provide reason |
| 253 | + * Do this before administrative action to confirm action and provide reason |
| 254 | + * @param params to store action paramaters |
| 255 | + * @param $item jQuery item containing the .fbd-item |
254 | 256 | */ |
255 | | - function beforeAction(params, $item){ |
256 | | - var inlineForm = '<span class="fbd-item-reason">\ |
257 | | - $1\ |
258 | | - <input class="fbd-action-reason" name="fb-action-reason" />\ |
259 | | - <button class="fbd-action-confirm">Confirm</button>\ |
260 | | - <button class="fbd-action-cancel">Cancel</button>\ |
261 | | - </span>' |
262 | | - .replace( /\$1/g, mw.msg( 'moodbar-action-reason' )); |
| 257 | + function confirmAction(params, $item){ |
| 258 | + |
| 259 | + var inlineForm = $('<span>').attr('class', 'fbd-item-reason') |
| 260 | + .append( $('<span>').html(mw.msg( 'moodbar-action-reason' )) ) |
| 261 | + .append( $('<input />').attr({'class':'fbd-action-reason', 'name':'fbd-action-reason'}) ) |
| 262 | + .append( $('<button>').attr('class', 'fbd-action-confirm').html( mw.msg('moodbar-feedback-action-confirm')) ) |
| 263 | + .append( $('<button>').attr('class', 'fbd-action-cancel').html( mw.msg('moodbar-feedback-action-cancel')) ) |
| 264 | + .append( $('<span>').attr('class', 'fbd-item-reason-msg') ) |
| 265 | + .append( $('<div>').attr('class', 'fbd-item-reason-msg') ); |
263 | 266 | |
264 | 267 | var storedParams = params; |
265 | 268 | var $storedItem = $item; |
— | — | @@ -267,16 +270,17 @@ |
268 | 271 | .empty(); |
269 | 272 | |
270 | 273 | $item.find('.fbd-item-message') |
271 | | - .append(inlineForm) |
272 | | - .end(); |
| 274 | + .append(inlineForm); |
273 | 275 | |
274 | 276 | $('.fbd-action-confirm').click( function() { |
275 | | - storedParams.reason = $item.find('.fbd-action-reason').val(); |
| 277 | + storedParams.reason = $storedItem.find('.fbd-action-reason').val(); |
276 | 278 | |
277 | 279 | if( storedParams.reason ) { |
278 | 280 | doAction(storedParams, $storedItem); |
279 | 281 | } else { |
280 | | - alert( mw.msg( 'moodbar-action-reason-required' ) ); |
| 282 | + inlineMessage($storedItem.find('.fbd-item-reason'), mw.msg( 'moodbar-action-reason-required' ), function() { |
| 283 | + reloadItem( $storedItem, true ); |
| 284 | + }); |
281 | 285 | } |
282 | 286 | |
283 | 287 | }); |
— | — | @@ -288,6 +292,8 @@ |
289 | 293 | |
290 | 294 | /** |
291 | 295 | * Execute an action on an item |
| 296 | + * @param params contains action parameters |
| 297 | + * @param $item jQuery item containing the .fbd-item |
292 | 298 | */ |
293 | 299 | function doAction( params, $item ) { |
294 | 300 | var item_id = $item.data('mbccontinue').split('|')[1]; |
— | — | @@ -328,7 +334,7 @@ |
329 | 335 | function restoreItem(e) { |
330 | 336 | var $item = $(this).closest('.fbd-item'); |
331 | 337 | |
332 | | - beforeAction( { 'mbaction' : 'restore' }, $item ); |
| 338 | + confirmAction( { 'mbaction' : 'restore' }, $item ); |
333 | 339 | e.preventDefault(); |
334 | 340 | } |
335 | 341 | |
— | — | @@ -337,11 +343,191 @@ |
338 | 344 | */ |
339 | 345 | function hideItem(e) { |
340 | 346 | var $item = $(this).closest('.fbd-item'); |
341 | | - |
342 | | - beforeAction( { 'mbaction' : 'hide' }, $item ); |
| 347 | + closeAllResponders(); //if any are open |
| 348 | + confirmAction( { 'mbaction' : 'hide' }, $item ); |
343 | 349 | e.preventDefault(); |
344 | 350 | } |
345 | 351 | |
| 352 | + /** |
| 353 | + * Method to close all responders. |
| 354 | + * Remove all .fbd-response-form from the dashboard |
| 355 | + */ |
| 356 | + function closeAllResponders() { |
| 357 | + |
| 358 | + $( '.fbd-item').each(function(index, value){ |
| 359 | + |
| 360 | + $link = $( this ).find('.fbd-respond-link'); |
| 361 | + if( $link.hasClass('responder-expanded') ) { |
| 362 | + |
| 363 | + $link.empty().html( mw.msg( 'moodbar-respond-collapsed' ) + ' ' + mw.msg( 'moodbar-respond-text' ) ) |
| 364 | + .removeClass('responder-expanded'); |
| 365 | + |
| 366 | + $( this ).find('.fbd-response-form').remove(); |
| 367 | + } |
| 368 | + }); |
| 369 | + } |
| 370 | + |
| 371 | + /** |
| 372 | + * Show the Response form for the item |
| 373 | + * Build the response form elements once |
| 374 | + * |
| 375 | + */ |
| 376 | + function showResponseForm(e){ |
| 377 | + |
| 378 | + if( $(this).hasClass('responder-expanded') ) { |
| 379 | + |
| 380 | + closeAllResponders(); |
| 381 | + |
| 382 | + } else { |
| 383 | + |
| 384 | + //init terms of use link |
| 385 | + var termsofuse = mw.html.element ('a', { |
| 386 | + 'href': mw.msg( 'moodbar-response-terms-of-use-link' ), |
| 387 | + 'title': mw.msg( 'moodbar-response-terms-of-use' ), |
| 388 | + 'target': '_new' |
| 389 | + }, mw.msg( 'moodbar-response-terms-of-use' ) ); |
| 390 | + |
| 391 | + //creative commons link |
| 392 | + var creativecommons = mw.html.element('a', { |
| 393 | + 'href': mw.msg ( 'moodbar-response-cc-link' ), |
| 394 | + 'title': mw.msg ( 'moodbar-response-cc' ), |
| 395 | + 'target': '_new' |
| 396 | + }, mw.msg ( 'moodbar-response-cc' ) ); |
| 397 | + |
| 398 | + //gfdl |
| 399 | + var gfdl = mw.html.element('a', { |
| 400 | + 'href': mw.msg( 'moodbar-response-gfdl-link' ), |
| 401 | + 'title': mw.msg( 'moodbar-response-gfdl' ), |
| 402 | + 'target': '_new' |
| 403 | + }, mw.msg( 'moodbar-response-gfdl' ) ); |
| 404 | + |
| 405 | + //ULA |
| 406 | + var ula = mw.msg( 'moodbar-response-ula' ) |
| 407 | + .replace ( /\$1/, mw.msg( 'moodbar-response-btn') ) |
| 408 | + .replace ( /\$2/, termsofuse) |
| 409 | + .replace ( /\$3/, creativecommons) |
| 410 | + .replace ( /\$4/, gfdl); |
| 411 | + |
| 412 | + //build form |
| 413 | + var inlineForm = $('<div>').attr( 'class', 'fbd-response-form' ) |
| 414 | + .append( |
| 415 | + $('<b>').html( mw.msg( 'moodbar-response-add' ) ) |
| 416 | + ).append( |
| 417 | + $('<small>').attr( 'class', 'fbd-text-gray' ).html( ' (' + mw.msg( 'moodbar-response-nosig' ) + ') ' ) |
| 418 | + ).append( |
| 419 | + $('<div>').attr( 'class', 'fbd-response-formNote' ) |
| 420 | + .append($('<small>') |
| 421 | + .append( |
| 422 | + $('<span>').attr( 'class', 'fbd-response-charCount' ) |
| 423 | + ).append( |
| 424 | + $('<span>').html( mw.msg( 'moodbar-form-note-dynamic' ).replace( /\$1/g, "" ) ) |
| 425 | + ) |
| 426 | + ) |
| 427 | + ).append( |
| 428 | + $('<textarea>').attr( { 'class':'fbd-response-text', 'name':'fbd-response-text' } ) |
| 429 | + ).append( |
| 430 | + $('<div>').attr('class', 'ula').html( ula ) |
| 431 | + ).append( |
| 432 | + $('<button>').attr( 'class', 'fbd-response-submit' ).html( mw.msg( 'moodbar-response-btn' ) + ' ' + mw.msg( 'moodbar-respond-collapsed' ) ) |
| 433 | + .attr({'disabled':'true'}) |
| 434 | + ).append( |
| 435 | + $('<div>').attr( 'style', 'clear:both' ) |
| 436 | + ); |
| 437 | + |
| 438 | + //get the feedbackItem |
| 439 | + var $item = $(this).closest('.fbd-item'); |
| 440 | + |
| 441 | + closeAllResponders(); |
| 442 | + |
| 443 | + $(this).empty().html( mw.msg( 'moodbar-respond-expanded' ) + ' ' + mw.msg( 'moodbar-respond-text' ) ) |
| 444 | + .addClass( 'responder-expanded' ) |
| 445 | + .end(); |
| 446 | + |
| 447 | + $item.append(inlineForm) |
| 448 | + .find('.fbd-response-text') |
| 449 | + .NobleCount('.fbd-response-charCount', {max_chars:5000}) |
| 450 | + .end() |
| 451 | + .find('.fbd-response-text') |
| 452 | + .keyup( function(event) { |
| 453 | + validateResponse($item); |
| 454 | + }) |
| 455 | + .end() |
| 456 | + .find('.fbd-response-submit') |
| 457 | + .click (function () { |
| 458 | + var fbResponse = $item.find('.fbd-response-text').val(); |
| 459 | + if( fbResponse ){ |
| 460 | + var clientData = $.client.profile(), |
| 461 | + item_id = $item.data('mbccontinue').split('|')[1], |
| 462 | + resData = { |
| 463 | + 'action':'feedbackdashboardresponse', |
| 464 | + 'useragent': clientData.name + '/' + clientData.versionNumber, |
| 465 | + 'system': clientData.platform, |
| 466 | + 'token': mw.config.get('mbEditToken'), |
| 467 | + 'response': fbResponse, |
| 468 | + 'feedback': item_id, |
| 469 | + 'format':'json' |
| 470 | + }; |
| 471 | + $item.find('.fbd-item-response').remove(); //remove feedback response link for duration of request |
| 472 | + var $spinner = $('<span class="mw-ajax-loader"> </span>'); |
| 473 | + $responseForm = $item.find('.fbd-response-form').empty().append( $spinner ); |
| 474 | + |
| 475 | + //send response |
| 476 | + $.ajax( { |
| 477 | + 'type': 'POST', |
| 478 | + 'url': mw.util.wikiScript( 'api' ), |
| 479 | + 'data': resData, |
| 480 | + 'success': function (data) { |
| 481 | + inlineMessage($responseForm, mw.msg( 'feedbackresponse-success' ), function() { |
| 482 | + closeAllResponders(); |
| 483 | + reloadItem( $item, true ); |
| 484 | + }); |
| 485 | + }, |
| 486 | + 'error': function( jqXHR, textStatus, errorThrown ) { |
| 487 | + //ajax error |
| 488 | + inlineMessage($responseForm, mw.msg( 'moodbar-feedback-ajaxerror' ), function() { |
| 489 | + closeAllResponders(); |
| 490 | + reloadItem( $item, true ); |
| 491 | + }); |
| 492 | + |
| 493 | + }, |
| 494 | + 'dataType': 'json' |
| 495 | + } ); |
| 496 | + |
| 497 | + } |
| 498 | + }) |
| 499 | + .end(); |
| 500 | + } |
| 501 | + e.preventDefault(); |
| 502 | + |
| 503 | + } |
| 504 | + |
| 505 | + /** |
| 506 | + * Toggle submit button from enabled to disabled |
| 507 | + * Depends on value of .fbd-response-text |
| 508 | + * @param $item jQuery item containing the .fbd-item |
| 509 | + */ |
| 510 | + function validateResponse($item) { |
| 511 | + if( $item.find('.fbd-response-text').val() !== "" ) { |
| 512 | + $item.find( '.fbd-response-submit').removeAttr('disabled'); |
| 513 | + } else { |
| 514 | + $item.find( '.fbd-response-submit').attr({'disabled':'true'}); |
| 515 | + } |
| 516 | + } |
| 517 | + |
| 518 | + /** |
| 519 | + * Send Message to item in regards with response |
| 520 | + * @param $el Element to display message inside of and fadeout |
| 521 | + * @param msg text to display |
| 522 | + * @callback to execute after fadeOut |
| 523 | + */ |
| 524 | + function inlineMessage( $el, msg, callback) { |
| 525 | + $el.empty() |
| 526 | + .html( msg ) |
| 527 | + .delay(2000) |
| 528 | + .fadeOut('slow', callback); |
| 529 | + } |
| 530 | + |
| 531 | + |
346 | 532 | // On-load stuff |
347 | 533 | |
348 | 534 | $('.fbd-item-show a').live( 'click', showHiddenItem ); |
— | — | @@ -350,6 +536,8 @@ |
351 | 537 | |
352 | 538 | $('.fbd-item-restore').live( 'click', restoreItem ); |
353 | 539 | |
| 540 | + $('.fbd-respond-link').live ('click', showResponseForm ); |
| 541 | + |
354 | 542 | $( '#fbd-filters' ).children( 'form' ).submit( function( e ) { |
355 | 543 | e.preventDefault(); |
356 | 544 | saveFormState(); |
Index: trunk/extensions/MoodBar/MoodBar.php |
— | — | @@ -138,7 +138,7 @@ |
139 | 139 | 'mediawiki.util', |
140 | 140 | 'ext.moodBar.init', // just in case |
141 | 141 | 'jquery.localize', |
142 | | - 'jquery.NobleCount', |
| 142 | + 'jquery.NobleCount', |
143 | 143 | 'jquery.moodBar', |
144 | 144 | ), |
145 | 145 | 'position' => 'bottom', |
— | — | @@ -146,14 +146,34 @@ |
147 | 147 | |
148 | 148 | $wgResourceModules['ext.moodBar.dashboard'] = $mbResourceTemplate + array( |
149 | 149 | 'scripts' => 'ext.moodBar.dashboard/ext.moodBar.dashboard.js', |
150 | | - 'dependencies' => array( 'mediawiki.util' ), |
| 150 | + 'dependencies' => array( |
| 151 | + 'mediawiki.util', |
| 152 | + 'jquery.NobleCount' |
| 153 | + ), |
151 | 154 | 'messages' => array( |
152 | 155 | 'moodbar-feedback-nomore', |
153 | 156 | 'moodbar-feedback-noresults', |
154 | 157 | 'moodbar-feedback-ajaxerror', |
155 | 158 | 'moodbar-feedback-action-error', |
156 | 159 | 'moodbar-action-reason', |
157 | | - 'moodbar-action-reason-required' |
| 160 | + 'moodbar-action-reason-required', |
| 161 | + 'moodbar-feedback-action-confirm', |
| 162 | + 'moodbar-feedback-action-cancel', |
| 163 | + 'moodbar-respond-text', |
| 164 | + 'moodbar-respond-collapsed', |
| 165 | + 'moodbar-respond-expanded', |
| 166 | + 'moodbar-response-add', |
| 167 | + 'moodbar-response-nosig', |
| 168 | + 'moodbar-response-btn', |
| 169 | + 'moodbar-form-note-dynamic', |
| 170 | + 'moodbar-response-ula', |
| 171 | + 'moodbar-response-terms-of-use', |
| 172 | + 'moodbar-response-terms-of-use-link', |
| 173 | + 'moodbar-response-cc', |
| 174 | + 'moodbar-response-cc-link', |
| 175 | + 'moodbar-response-gfdl', |
| 176 | + 'moodbar-response-gfdl-link', |
| 177 | + 'feedbackresponse-success', |
158 | 178 | ), |
159 | 179 | ); |
160 | 180 | |