Index: trunk/extensions/LiquidThreads/LqtFunctions.php |
— | — | @@ -49,4 +49,3 @@ |
50 | 50 | array( 'LqtParserFunctions', 'useLiquidThreads' ) ); |
51 | 51 | return true; |
52 | 52 | } |
53 | | - |
Index: trunk/extensions/LiquidThreads/i18n/Lqt.i18n.php |
— | — | @@ -237,6 +237,10 @@ |
238 | 238 | 'lqt-search-legend' => 'Search discussions on this page', |
239 | 239 | 'lqt-search-label' => 'Search terms:', |
240 | 240 | 'lqt-search-button' => 'Search', |
| 241 | + |
| 242 | + // Some AJAX stuff |
| 243 | + 'lqt-ajax-updated' => 'This thread has new posts.', |
| 244 | + 'lqt-ajax-update-link' => 'Click here to load the latest posts.', |
241 | 245 | ); |
242 | 246 | |
243 | 247 | /** Message documentation (Message documentation) |
Index: trunk/extensions/LiquidThreads/lqt.css |
— | — | @@ -451,3 +451,13 @@ |
452 | 452 | /* float: left;*/ |
453 | 453 | font-weight: bold; |
454 | 454 | } |
| 455 | + |
| 456 | +.lqt-updated-notification { |
| 457 | + text-align: center; |
| 458 | + margin-left: 20%; |
| 459 | + margin-right: 20%; |
| 460 | + padding: 1em; |
| 461 | + font-weight: bold; |
| 462 | + border: 1px solid #dddddd; |
| 463 | + background-color: #eeeeee; |
| 464 | +} |
Index: trunk/extensions/LiquidThreads/classes/View.php |
— | — | @@ -619,7 +619,8 @@ |
620 | 620 | static function exportJSLocalisation() { |
621 | 621 | wfLoadExtensionMessages( 'LiquidThreads' ); |
622 | 622 | |
623 | | - $messages = array( 'lqt-quote-intro', 'lqt-quote' ); |
| 623 | + $messages = array( 'lqt-quote-intro', 'lqt-quote', 'lqt-ajax-updated', |
| 624 | + 'lqt-ajax-update-link' ); |
624 | 625 | $data = array(); |
625 | 626 | |
626 | 627 | foreach( $messages as $msg ) { |
— | — | @@ -978,6 +979,7 @@ |
979 | 980 | $html = ''; |
980 | 981 | |
981 | 982 | $html .= Xml::element( 'a', array( 'name' => $this->anchorName($thread) ), ' ' ); |
| 983 | + |
982 | 984 | $html .= $this->showThreadHeading( $thread ); |
983 | 985 | |
984 | 986 | $class = $this->threadDivClass( $thread ); |
— | — | @@ -986,12 +988,20 @@ |
987 | 989 | } elseif ($levelNum == $totalInLevel) { |
988 | 990 | $class .= ' lqt-thread-last'; |
989 | 991 | } |
| 992 | + |
990 | 993 | $html .= Xml::openElement( 'div', array( 'class' => $class, |
991 | 994 | 'id' => 'lqt_thread_id_'. $thread->id() ) ); |
992 | 995 | |
| 996 | + // Modified time for topmost threads... |
| 997 | + if ( $thread->isTopmostThread() ) { |
| 998 | + $html .= Xml::hidden( 'lqt-thread-modified-'.$thread->id(), |
| 999 | + wfTimestamp( TS_MW, $thread->modified() ), |
| 1000 | + array( 'id' => 'lqt-thread-modified-'.$thread->id(), |
| 1001 | + 'class' => 'lqt-thread-modified' ) ); |
| 1002 | + } |
| 1003 | + |
993 | 1004 | // Flush output to display thread |
994 | 1005 | $this->output->addHTML( $html ); |
995 | | - |
996 | 1006 | $this->output->addHTML( Xml::openElement( 'div', |
997 | 1007 | array( 'class' => 'lqt-post-wrapper' ) ) ); |
998 | 1008 | $this->showSingleThread( $thread ); |
— | — | @@ -1041,8 +1051,9 @@ |
1042 | 1052 | $levelClass = 'lqt-thread-nest-'.$this->threadNestingLevel; |
1043 | 1053 | $alternatingType = ($this->threadNestingLevel % 2) ? 'odd' : 'even'; |
1044 | 1054 | $alternatingClass = "lqt-thread-$alternatingType"; |
| 1055 | + $topmostClass = $thread->isTopmostThread() ? ' lqt-thread-topmost' : ''; |
1045 | 1056 | |
1046 | | - return "lqt_thread $levelClass $alternatingClass"; |
| 1057 | + return "lqt_thread $levelClass $alternatingClass$topmostClass"; |
1047 | 1058 | } |
1048 | 1059 | |
1049 | 1060 | function getSummary( $t ) { |
Index: trunk/extensions/LiquidThreads/lqt.js |
— | — | @@ -218,6 +218,53 @@ |
219 | 219 | |
220 | 220 | menuTrigger.show(); |
221 | 221 | }, |
| 222 | + |
| 223 | + 'checkForUpdates' : function() { |
| 224 | + var threadModifiedTS = {}; |
| 225 | + var threads = []; |
| 226 | + |
| 227 | + $j('.lqt-thread-topmost').each( function() { |
| 228 | + var tsField = $j(this).find('.lqt-thread-modified'); |
| 229 | + var oldTS = tsField.val(); |
| 230 | + // Prefix is lqt-thread-modified- |
| 231 | + var threadID = tsField.attr('id').substr( "lqt-thread-modified-".length ); |
| 232 | + |
| 233 | + threadModifiedTS[threadID] = oldTS; |
| 234 | + threads.push(threadID); |
| 235 | + } ); |
| 236 | + |
| 237 | + var getData = { 'action' : 'query', 'list' : 'threads', 'lqtid' : threads.join('|'), |
| 238 | + 'format' : 'json', 'lqtprop' : 'id|subject|parent|modified' }; |
| 239 | + |
| 240 | + $j.get( wgScriptPath+'/api.php', getData, |
| 241 | + function(data) { |
| 242 | + var threads = data.query.threads; |
| 243 | + |
| 244 | + $j.each( threads, function( i, thread ) { |
| 245 | + var threadID = thread.id; |
| 246 | + var threadModified = thread.modified; |
| 247 | + |
| 248 | + if ( threadModified != threadModifiedTS[threadID] ) { |
| 249 | + liquidThreads.showUpdated(threadID); |
| 250 | + } |
| 251 | + } ); |
| 252 | + }, 'json' ); |
| 253 | + }, |
| 254 | + |
| 255 | + 'showUpdated' : function(id) { |
| 256 | + // Check if there's already an updated marker here |
| 257 | + var threadObject = $j("#lqt_thread_id_"+id); |
| 258 | + |
| 259 | + if ( threadObject.find('.lqt-updated-notification').length ) { |
| 260 | + return; |
| 261 | + } |
| 262 | + |
| 263 | + var notifier = $j('<div/>'); |
| 264 | + notifier.text( wgLqtMessages['lqt-ajax-updated'] ); |
| 265 | + notifier.addClass( 'lqt-updated-notification' ); |
| 266 | + |
| 267 | + threadObject.prepend(notifier); |
| 268 | + } |
222 | 269 | } |
223 | 270 | |
224 | 271 | js2AddOnloadHook( function() { |
— | — | @@ -253,5 +300,8 @@ |
254 | 301 | |
255 | 302 | // Show quote buttons |
256 | 303 | liquidThreads.showQuoteButtons(); |
| 304 | + |
| 305 | + // Set up periodic update checking |
| 306 | + setInterval( liquidThreads.checkForUpdates, 30000 ); |
257 | 307 | } ); |
258 | 308 | |