Index: trunk/extensions/LiquidThreads/LiquidThreads.php |
— | — | @@ -160,6 +160,8 @@ |
161 | 161 | $wgAPIListModules['threads'] = 'ApiQueryLQTThreads'; |
162 | 162 | $wgAutoloadClasses['ApiFeedLQTThreads'] = "$dir/api/ApiFeedLQTThreads.php"; |
163 | 163 | $wgAPIModules['feedthreads'] = 'ApiFeedLQTThreads'; |
| 164 | +$wgAutoloadClasses['ApiThreadAction'] = "$dir/api/ApiThreadAction.php"; |
| 165 | +$wgAPIModules['threadaction'] = 'ApiThreadAction'; |
164 | 166 | |
165 | 167 | /** CONFIGURATION SECTION */ |
166 | 168 | |
Index: trunk/extensions/LiquidThreads/newmessages.js |
— | — | @@ -0,0 +1,52 @@ |
| 2 | + |
| 3 | +liquidThreads.doMarkRead = |
| 4 | + function(e) { |
| 5 | + e.preventDefault(); |
| 6 | + |
| 7 | + var button = $j(this); |
| 8 | + |
| 9 | + // Find the operand. |
| 10 | + var form = button.closest('form.lqt_newmessages_read_button'); |
| 11 | + var operand = form.find('input[name=lqt_operand]').val(); |
| 12 | + var threads = operand.replace( ',', '|' ); |
| 13 | + |
| 14 | + var getTokenParams = |
| 15 | + { |
| 16 | + 'action' : 'query', |
| 17 | + 'prop' : 'info', |
| 18 | + 'intoken' : 'edit', |
| 19 | + 'titles' : 'Some Title', |
| 20 | + 'format' : 'json' |
| 21 | + }; |
| 22 | + |
| 23 | + var spinner = $j('<div class="mw-ajax-loader"/>'); |
| 24 | + $j(button).before( spinner ); |
| 25 | + |
| 26 | + $j.get( wgScriptPath+'/api'+wgScriptExtension, getTokenParams, |
| 27 | + function( data ) { |
| 28 | + var token = data.query.pages[-1].edittoken; |
| 29 | + |
| 30 | + var markReadParameters = |
| 31 | + { |
| 32 | + 'action' : 'threadaction', |
| 33 | + 'threadaction' : 'markread', |
| 34 | + 'format' : 'json', |
| 35 | + 'thread' : threads, |
| 36 | + 'token' : token |
| 37 | + } |
| 38 | + |
| 39 | + $j.post( wgScriptPath+'/api'+wgScriptExtension, |
| 40 | + markReadParameters, |
| 41 | + function(reply) { |
| 42 | + button.closest('tr').remove(); |
| 43 | + spinner.remove(); |
| 44 | + }, 'json' ); |
| 45 | + }, 'json' ); |
| 46 | + } |
| 47 | + |
| 48 | +// Setup |
| 49 | +$j( function() { |
| 50 | + var buttons = $j('.lqt-read-button'); |
| 51 | + |
| 52 | + buttons.click( liquidThreads.doMarkRead ); |
| 53 | +} ); |
Index: trunk/extensions/LiquidThreads/classes/View.php |
— | — | @@ -728,9 +728,6 @@ |
729 | 729 | *************************/ |
730 | 730 | |
731 | 731 | static function addJSandCSS() { |
732 | | - // Changed this to be static so that we can call it from |
733 | | - // wfLqtBeforeWatchlistHook. |
734 | | - |
735 | 732 | if ( self::$stylesAndScriptsDone ) { |
736 | 733 | return; |
737 | 734 | } |
Index: trunk/extensions/LiquidThreads/pages/NewUserMessagesView.php |
— | — | @@ -13,8 +13,9 @@ |
14 | 14 | $html = ''; |
15 | 15 | $html .= Xml::hidden( 'lqt_method', 'mark_as_read' ); |
16 | 16 | $html .= Xml::hidden( 'lqt_operand', $ids_s ); |
17 | | - $html .= Xml::submitButton( $label, array( 'name' => 'lqt_read_button', |
18 | | - 'title' => $title ) ); |
| 17 | + $html .= Xml::submitButton( $label, |
| 18 | + array( 'name' => 'lqt_read_button', |
| 19 | + 'title' => $title, 'class' => 'lqt-read-button' ) ); |
19 | 20 | $html = Xml::tags( 'form', array( 'method' => 'post', 'class' => $class ), $html ); |
20 | 21 | |
21 | 22 | return $html; |
— | — | @@ -72,6 +73,13 @@ |
73 | 74 | |
74 | 75 | function showOnce() { |
75 | 76 | self::addJSandCSS(); |
| 77 | + |
| 78 | + static $scriptDone = false; |
| 79 | + |
| 80 | + if ( !$scriptDone ) { |
| 81 | + global $wgOut, $wgScriptPath; |
| 82 | + $wgOut->addScriptFile( "{$wgScriptPath}/extensions/LiquidThreads/newmessages.js" ); |
| 83 | + } |
76 | 84 | |
77 | 85 | if ( $this->request->wasPosted() ) { |
78 | 86 | // If they just viewed this page, maybe they still want that notice. |
Index: trunk/extensions/LiquidThreads/api/ApiThreadAction.php |
— | — | @@ -0,0 +1,116 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +class ApiThreadAction extends ApiBase { |
| 5 | + |
| 6 | + public function getDescription() { |
| 7 | + return 'Allows actions to be taken on threads and posts in threaded discussions.'; |
| 8 | + } |
| 9 | + |
| 10 | + public function getActions() { |
| 11 | + return array( |
| 12 | + 'markread' => 'actionMarkRead', |
| 13 | + 'markunread' => 'actionMarkUnread', |
| 14 | +// 'reply', // Not implemented |
| 15 | +// 'newtopic', // Not implemented |
| 16 | + ); |
| 17 | + } |
| 18 | + |
| 19 | + protected function getParamDescription() { |
| 20 | + return array( |
| 21 | + 'thread' => 'A list (pipe-separated) of thread IDs or titles to act on', |
| 22 | + 'threadaction' => 'The action to take', |
| 23 | + 'token' => 'An edit token (from ?action=query&prop=info&intoken=edit)', |
| 24 | + 'talkpage' => 'The talkpage to act on (if applicable)', |
| 25 | + ); |
| 26 | + } |
| 27 | + |
| 28 | + public function getExamples() { |
| 29 | + return array( |
| 30 | + |
| 31 | + ); |
| 32 | + } |
| 33 | + |
| 34 | + public function getAllowedParams() { |
| 35 | + return array( |
| 36 | + 'thread' => array( |
| 37 | + ApiBase::PARAM_ISMULTI => true, |
| 38 | + ), |
| 39 | + 'talkpage' => null, |
| 40 | + 'threadaction' => array( |
| 41 | + ApiBase::PARAM_TYPE => array_keys( $this->getActions() ), |
| 42 | + ), |
| 43 | + 'token' => null, |
| 44 | + ); |
| 45 | + } |
| 46 | + |
| 47 | + public function mustBePosted() { /*return true;*/ } |
| 48 | + |
| 49 | + public function isWriteMode() { |
| 50 | + return true; |
| 51 | + } |
| 52 | + |
| 53 | + public function execute() { |
| 54 | + $params = $this->extractRequestParams(); |
| 55 | + |
| 56 | + global $wgUser; |
| 57 | + |
| 58 | + if ( empty( $params['token'] ) || |
| 59 | + !$wgUser->matchEditToken( $params['token'] ) ) { |
| 60 | + $this->dieUsage( 'sessionfailure' ); |
| 61 | + return; |
| 62 | + } |
| 63 | + |
| 64 | + if ( empty( $params['threadaction'] ) ) { |
| 65 | + $this->dieUsage( 'missing-param', 'action' ); |
| 66 | + return; |
| 67 | + } |
| 68 | + |
| 69 | + // Pull the threads from the parameters |
| 70 | + $threads = array(); |
| 71 | + foreach( $params['thread'] as $thread ) { |
| 72 | + if ( is_numeric( $thread ) ) { |
| 73 | + $threads[] = Threads::withId( $thread ); |
| 74 | + } else { |
| 75 | + $title = Title::newFromText( $thread ); |
| 76 | + $article = new Article( $title ); |
| 77 | + $threads[] = Threads::withRoot( $article ); |
| 78 | + } |
| 79 | + } |
| 80 | + |
| 81 | + // Find the appropriate module |
| 82 | + $action = $params['threadaction']; |
| 83 | + $actions = $this->getActions(); |
| 84 | + |
| 85 | + $method = $actions[$action]; |
| 86 | + |
| 87 | + call_user_func_array( array( $this, $method ), array( $threads, $params ) ); |
| 88 | + } |
| 89 | + |
| 90 | + public function actionMarkRead( $threads, $params ) { |
| 91 | + global $wgUser; |
| 92 | + |
| 93 | + foreach( $threads as $t ) { |
| 94 | + NewMessages::markThreadAsReadByUser( $t, $wgUser ); |
| 95 | + } |
| 96 | + |
| 97 | + $result = array( 'result' => 'Success', 'action' => 'markread' ); |
| 98 | + |
| 99 | + $this->getResult()->addValue( null, 'threadaction', $result ); |
| 100 | + } |
| 101 | + |
| 102 | + public function actionMarkUnread( $threads, $params ) { |
| 103 | + global $wgUser; |
| 104 | + |
| 105 | + foreach( $threads as $t ) { |
| 106 | + NewMessages::markThreadAsUnreadByUser( $t, $wgUser ); |
| 107 | + } |
| 108 | + |
| 109 | + $result = array( 'result' => 'Success', 'action' => 'markunread' ); |
| 110 | + |
| 111 | + $this->getResult()->addValue( null, 'threadaction', $result ); |
| 112 | + } |
| 113 | + |
| 114 | + public function getVersion() { |
| 115 | + return __CLASS__ . ': $Id: $'; |
| 116 | + } |
| 117 | +} |
Index: trunk/extensions/LiquidThreads/lqt.js |
— | — | @@ -424,7 +424,7 @@ |
425 | 425 | var apiParams = { 'action' : 'query', 'list' : 'threads', 'thid' : threadId, |
426 | 426 | 'format' : 'json', 'thrender' : '1', 'thprop' : 'id' }; |
427 | 427 | |
428 | | - $j.get( wgScriptPath+'/api.php', apiParams, |
| 428 | + $j.get( wgScriptPath+'/api'+wgScriptExtension, apiParams, |
429 | 429 | function(data) { |
430 | 430 | // Interpret |
431 | 431 | var content = data.query.threads[0].content; |