Index: trunk/extensions/Storyboard/storyboard.sql |
— | — | @@ -13,7 +13,8 @@ |
14 | 14 | story_modified CHAR(14) binary NOT NULL default '', |
15 | 15 | story_created CHAR(14) binary NOT NULL default '', |
16 | 16 | story_is_published TINYINT NOT NULL default '0', |
17 | | - story_is_hidden TINYINT NOT NULL default '0' |
| 17 | + story_is_hidden TINYINT NOT NULL default '0', |
| 18 | + story_image_hidden TINYINT NOT NULL default '0' |
18 | 19 | ) /*$wgDBTableOptions*/; |
19 | 20 | |
20 | 21 | CREATE INDEX story_published_modified ON /*$wgDBprefix*/storyboard (story_is_published, story_modified); |
Index: trunk/extensions/Storyboard/Storyboard.i18n.php |
— | — | @@ -31,6 +31,9 @@ |
32 | 32 | 'storyboard-unpublish' => 'Unpublish', |
33 | 33 | 'storyboard-reviewed' => 'Reviewed', |
34 | 34 | 'storyboard-unreviewed' => 'Unreviewed', |
| 35 | + 'storyboard-hideimage' => 'Hide image', |
| 36 | + 'storyboard-unhideimage' => 'Show image', |
| 37 | + 'storyboard-deleteimage' => 'Delete image', |
35 | 38 | |
36 | 39 | // Story submission |
37 | 40 | 'storyboard-yourname' => 'Your name', |
Index: trunk/extensions/Storyboard/tags/Storyboard/storyboard.css |
— | — | @@ -1,7 +1,7 @@ |
2 | 2 | /** |
3 | 3 | * Css for <storyboard> tags of the Storyboard extension. |
4 | 4 | * |
5 | | - * @file Storyboard.css |
| 5 | + * @file storyboard.css |
6 | 6 | * @ingroup Storyboard |
7 | 7 | * |
8 | 8 | * @author Jeroen De Dauw |
— | — | @@ -24,32 +24,4 @@ |
25 | 25 | .storyboard .storyboard-empty .storyboard-box { |
26 | 26 | border: 1px solid #ddd; |
27 | 27 | background: #FCFCFC url(../../images/storyboard-loader.gif) no-repeat scroll center center; |
28 | | -} |
29 | | -.storyboard-sharing { |
30 | | - height: 30px; |
31 | | - width: 110px; |
32 | | - float: right; |
33 | | -} |
34 | | -.storyboard-sharing-item { |
35 | | - float: left; |
36 | | - padding-right: 5px; |
37 | | -} |
38 | | -.storyboard-header { |
39 | | - margin: 10px 0px 10px 15px; |
40 | | - height: 21px; |
41 | | -} |
42 | | -.storyboard-title { |
43 | | - font: 16px "Lucida Sans", Verdana; |
44 | | - font-weight: bold; |
45 | | - float: left; |
46 | | - overflow: hidden; |
47 | | -} |
48 | | -.storyboard-text { |
49 | | - margin-left: 15px; |
50 | | - float: left; |
51 | | - overflow: hidden; |
52 | | -} |
53 | | -.storyboard-image { |
54 | | - margin: 5px 15px 0px 15px; |
55 | | - float: right; |
56 | 28 | } |
\ No newline at end of file |
Index: trunk/extensions/Storyboard/tags/Storyboard/storyboard.js |
— | — | @@ -29,13 +29,15 @@ |
30 | 30 | var story = data.query.stories[i]; |
31 | 31 | var $storyBody = $( "<div />" ).addClass( "storyboard-box" ); |
32 | 32 | |
33 | | - var $header = $( "<div />" ).addClass( "storyboard-header" ).appendTo( $storyBody ); |
34 | | - $( "<div />" ).addClass( "storyboard-title" ).text( story.title ).appendTo( $header ); |
| 33 | + var $header = $( "<div />" ).addClass( "story-header" ).appendTo( $storyBody ); |
| 34 | + $( "<div />" ).addClass( "story-title" ).text( story.title ).appendTo( $header ); |
35 | 35 | |
| 36 | + // TODO: move social sharing to a pop-up that's triggered by a link above each storyboard-box |
| 37 | + |
36 | 38 | $( "<div />" ) |
37 | | - .addClass( "storyboard-sharing" ) |
| 39 | + .addClass( "story-sharing" ) |
38 | 40 | .append( |
39 | | - $( "<div />" ).addClass( "storyboard-sharing-item" ).append( |
| 41 | + $( "<div />" ).addClass( "story-sharing-item" ).append( |
40 | 42 | $( "<a />" ).attr( { |
41 | 43 | "target": "_blank", |
42 | 44 | "href": "http://delicious.com/save?jump=yes&url=" + "" |
— | — | @@ -46,7 +48,7 @@ |
47 | 49 | ) |
48 | 50 | ) //TODO |
49 | 51 | .append( |
50 | | - $( "<div />" ).addClass( "storyboard-sharing-item" ).append( |
| 52 | + $( "<div />" ).addClass( "story-sharing-item" ).append( |
51 | 53 | $( "<a />" ).attr( { |
52 | 54 | "target": "_blank", |
53 | 55 | "href": "http://www.facebook.com/sharer.php?u=" + "" + "&t=" + story.title |
— | — | @@ -57,7 +59,7 @@ |
58 | 60 | ) |
59 | 61 | ) //TODO |
60 | 62 | .append( |
61 | | - $( "<div />" ).addClass( "storyboard-sharing-item" ).append( |
| 63 | + $( "<div />" ).addClass( "story-sharing-item" ).append( |
62 | 64 | $( "<a />" ).attr( { |
63 | 65 | "target": "_blank", |
64 | 66 | "href": "http://twitter.com/home?status=" + "" |
— | — | @@ -69,15 +71,17 @@ |
70 | 72 | ) //TODO |
71 | 73 | .appendTo( $header ); |
72 | 74 | |
73 | | - $storyBody.append( $( "<div />" ).addClass( "storyboard-text" ) |
| 75 | + $storyBody.append( $( "<div />" ).addClass( "story-text" ) |
74 | 76 | .text( story["*"] ) |
75 | 77 | .prepend( $( "<img />" ) |
76 | 78 | // TODO: replace by wgScriptPath + path/to/scropped/img |
77 | 79 | .attr( "src", "http://upload.wikimedia.org/wikipedia/mediawiki/9/99/SemanticMaps.png" ) |
78 | | - .addClass( "storyboard-image" ) |
| 80 | + .addClass( "story-image" ) |
79 | 81 | ) |
80 | 82 | ); |
81 | 83 | |
| 84 | + // TODO: add delete button that hides the story from the storyboard (=unpublish+hide?) |
| 85 | + |
82 | 86 | $div.append( $storyBody ); |
83 | 87 | } |
84 | 88 | $storyboard.html( $div ); |
Index: trunk/extensions/Storyboard/tags/Storyboard/Storyboard_body.php |
— | — | @@ -19,6 +19,7 @@ |
20 | 20 | public static function render( $input, $args, $parser, $frame ) { |
21 | 21 | global $wgOut, $wgJsMimeType, $wgScriptPath, $egStoryboardScriptPath, $egStoryboardWidth, $egStoryboardHeight; |
22 | 22 | |
| 23 | + $wgOut->addStyle( $egStoryboardScriptPath . '/story.css' ); |
23 | 24 | $wgOut->addStyle( $egStoryboardScriptPath . '/tags/Storyboard/storyboard.css' ); |
24 | 25 | $wgOut->includeJQuery(); |
25 | 26 | // TODO: Combine+minfiy JS files, add switch to use combined+minified version |
Index: trunk/extensions/Storyboard/specials/StoryReview/StoryReview_body.php |
— | — | @@ -35,11 +35,13 @@ |
36 | 36 | } |
37 | 37 | |
38 | 38 | private function addOutput() { |
39 | | - global $wgOut; |
| 39 | + global $wgOut, $egStoryboardScriptPath; |
40 | 40 | |
41 | 41 | $wgOut->setPageTitle( wfMsg( 'storyboard-storyreview' ) ); |
42 | 42 | |
| 43 | + $wgOut->addStyle( $egStoryboardScriptPath . '/story.css' ); |
43 | 44 | $wgOut->includeJQuery(); |
| 45 | + $wgOut->addScriptFile( $egStoryboardScriptPath . '/specials/StoryReview/storyreview.js' ); |
44 | 46 | |
45 | 47 | // Get a slave db object to do read operations against. |
46 | 48 | $dbr = wfGetDB( DB_SLAVE ); |
— | — | @@ -52,7 +54,8 @@ |
53 | 55 | 'story_author_name', |
54 | 56 | 'story_title', |
55 | 57 | 'story_text', |
56 | | - 'story_is_published' |
| 58 | + 'story_is_published', |
| 59 | + 'story_image_hidden' |
57 | 60 | ), |
58 | 61 | array( 'story_is_hidden' => 0 ) |
59 | 62 | ); |
— | — | @@ -64,10 +67,10 @@ |
65 | 68 | // Loop through all stories, get their html, and add it to the appropriate string. |
66 | 69 | while ( $story = $dbr->fetchObject( $stories ) ) { |
67 | 70 | if ( $story->story_is_published ) { |
68 | | - $reviewed .= $this->getStorySegments( $story, $story->story_is_published ); |
| 71 | + $reviewed .= $this->getStorySegments( $story ); |
69 | 72 | } |
70 | 73 | else { |
71 | | - $unreviewed .= $this->getStorySegments( $story, $story->story_is_published ); |
| 74 | + $unreviewed .= $this->getStorySegments( $story ); |
72 | 75 | } |
73 | 76 | } |
74 | 77 | |
— | — | @@ -77,13 +80,9 @@ |
78 | 81 | // Output the html for the stories. |
79 | 82 | $wgOut->addHTML( <<<EOT |
80 | 83 | <h2>$unrevMsg</h2> |
81 | | - <table width="100%"> |
82 | 84 | $unreviewed |
83 | | - </table> |
84 | 85 | <h2>$revMsg</h2> |
85 | | - <table width="100%"> |
86 | | - $reviewed |
87 | | - </table> |
| 86 | + $reviewed |
88 | 87 | EOT |
89 | 88 | ); |
90 | 89 | } |
— | — | @@ -95,37 +94,43 @@ |
96 | 95 | * |
97 | 96 | * @return string |
98 | 97 | */ |
99 | | - private function getStorySegments( $story, $published ) { |
| 98 | + private function getStorySegments( $story ) { |
100 | 99 | $imageSrc = 'http://upload.wikimedia.org/wikipedia/mediawiki/9/99/SemanticMaps.png'; // TODO: get cropped image here |
| 100 | + |
101 | 101 | $title = htmlspecialchars( $story->story_title ); |
102 | 102 | $text = htmlspecialchars( $story->story_text ); |
103 | | - $publish = $published ? wfMsg( 'storyboard-unpublish' ) : wfMsg( 'storyboard-publish' ); |
104 | | - $edit = wfMsg( 'edit' ); |
105 | | - $hide = wfMsg( 'hide' ); |
106 | 103 | |
| 104 | + $publishAction = $story->story_is_published ? 'unpublish' : 'publish'; |
| 105 | + $publishMsg = wfMsg( "storyboard-$publishAction" ); |
| 106 | + |
| 107 | + $imageAction = $story->story_image_hidden ? 'unhideimage' : 'hideimage'; |
| 108 | + $imageMsg = wfMsg( "storyboard-$imageAction" ); |
| 109 | + |
| 110 | + $editMsg = wfMsg( 'edit' ); |
| 111 | + $hideMsg = wfMsg( 'hide' ); |
| 112 | + $deleteImageMsg = wfMsg( 'storyboard-deleteimage' ); |
| 113 | + |
107 | 114 | return <<<EOT |
108 | | - <tr> |
109 | | - <td> |
110 | | - <table width="100%" border="1"> |
111 | | - <tr> |
112 | | - <td rowspan="2" width="200px"> |
113 | | - <img src="$imageSrc" /> |
114 | | - </td> |
115 | | - <td> |
116 | | - <b>$title</b> |
117 | | - <br />$text |
118 | | - </td> |
119 | | - </tr> |
120 | | - <tr> |
121 | | - <td align="center" height="35"> |
122 | | - <button type="button">$publish</button> |
123 | | - <button type="button">$edit</button> |
124 | | - <button type="button">$hide</button> |
125 | | - </td> |
126 | | - </tr> |
127 | | - </table> |
128 | | - </td> |
129 | | - </tr> |
| 115 | + <table width="100%" border="1" id="story_$story->story_id"> |
| 116 | + <tr> |
| 117 | + <td> |
| 118 | + <div class="story"> |
| 119 | + <img src="http://upload.wikimedia.org/wikipedia/mediawiki/9/99/SemanticMaps.png" class="story-image"> |
| 120 | + <div class="story-title">$title</div><br /> |
| 121 | + $text |
| 122 | + </div> |
| 123 | + </td> |
| 124 | + </tr> |
| 125 | + <tr> |
| 126 | + <td align="center" height="35"> |
| 127 | + <button type="button" onclick="doStoryAction( this, $story->story_id, '$publishAction' )">$publishMsg</button> |
| 128 | + <button type="button" onclick="">$editMsg</button> |
| 129 | + <button type="button" onclick="doStoryAction( this, $story->story_id, 'hide' )">$hideMsg</button> |
| 130 | + <button type="button" onclick="doStoryAction( this, $story->story_id, '$imageAction' )">$imageMsg</button> |
| 131 | + <button type="button" onclick="deleteStoryImage( this, $story->story_id )">$deleteImageMsg</button> |
| 132 | + </td> |
| 133 | + </tr> |
| 134 | + </table> |
130 | 135 | EOT; |
131 | 136 | } |
132 | 137 | } |
\ No newline at end of file |
Index: trunk/extensions/Storyboard/specials/StoryReview/storyreview.js |
— | — | @@ -0,0 +1,37 @@ |
| 2 | +//(function($) { |
| 3 | + |
| 4 | + function doStoryAction( sender, storyid, action ) { |
| 5 | + sender.disabled = true; |
| 6 | + |
| 7 | + jQuery.getJSON( wgScriptPath + '/api.php', |
| 8 | + { |
| 9 | + 'action': 'storyreview', |
| 10 | + 'format': 'json', |
| 11 | + 'storyid': storyid, |
| 12 | + 'storyaction': action |
| 13 | + }, |
| 14 | + function( data ) { |
| 15 | + if ( data.result ) { |
| 16 | + switch( data.result.action ) { |
| 17 | + case 'publish' : case 'unpublish' : case 'hide' : |
| 18 | + jQuery( '#story_' + data.result.id ).slideUp( 'slow', function () { |
| 19 | + jQuery( this ).remove(); |
| 20 | + } ); |
| 21 | + // TODO: would be neat to update the other list when doing an (un)publish here |
| 22 | + break; |
| 23 | + // TODO: add handling for the other actions |
| 24 | + } |
| 25 | + } else { |
| 26 | + alert( 'An error occured:\n' + data.error.info ); // TODO: i18n |
| 27 | + } |
| 28 | + } |
| 29 | + ); |
| 30 | + } |
| 31 | + |
| 32 | + function deleteStoryImage( sender, storyid ) { |
| 33 | + if ( confirm( 'Are you sure you want to permanently delete this stories image?' ) ) { // TODO: i18n |
| 34 | + doStoryAction( sender, storyid, 'deleteimage' ) |
| 35 | + } |
| 36 | + } |
| 37 | + |
| 38 | +//})(jQuery); |
\ No newline at end of file |
Property changes on: trunk/extensions/Storyboard/specials/StoryReview/storyreview.js |
___________________________________________________________________ |
Name: svn:eol-style |
1 | 39 | + native |
Index: trunk/extensions/Storyboard/story.css |
— | — | @@ -0,0 +1,35 @@ |
| 2 | +/** |
| 3 | + * Css for stories, used at variouse places in the Storyboard extension. |
| 4 | + * |
| 5 | + * @file story.css |
| 6 | + * @ingroup Storyboard |
| 7 | + * |
| 8 | + * @author Jeroen De Dauw |
| 9 | + */ |
| 10 | + |
| 11 | +.story { |
| 12 | + margin-left: 15px; |
| 13 | + margin-top: 5px; |
| 14 | + float: left; |
| 15 | + overflow: hidden; |
| 16 | +} |
| 17 | +.story-title { |
| 18 | + font: 16px "Lucida Sans", Verdana; |
| 19 | + font-weight: bold; |
| 20 | + float: left; |
| 21 | + overflow: hidden; |
| 22 | +} |
| 23 | +.story-image { |
| 24 | + margin: 5px 15px 0px 15px; |
| 25 | + float: right; |
| 26 | +} |
| 27 | + |
| 28 | +.story-sharing { |
| 29 | + height: 30px; |
| 30 | + width: 110px; |
| 31 | + float: right; |
| 32 | +} |
| 33 | +.story-sharing-item { |
| 34 | + float: left; |
| 35 | + padding-right: 5px; |
| 36 | +} |
\ No newline at end of file |
Property changes on: trunk/extensions/Storyboard/story.css |
___________________________________________________________________ |
Name: svn:eol-style |
1 | 37 | + native |
Index: trunk/extensions/Storyboard/api/ApiStoryReview.php |
— | — | @@ -49,16 +49,15 @@ |
50 | 50 | $params = $this->extractRequestParams(); |
51 | 51 | |
52 | 52 | // Check required parameters |
53 | | - if ( !array_key_exists( 'storyid', $params ) ) { |
| 53 | + if ( !isset( $params['storyid'] ) ) { |
54 | 54 | $this->dieUsageMsg( array( 'missingparam', 'storyid' ) ); |
55 | 55 | } |
56 | | - if ( !array_key_exists( 'storyaction', $params ) ) { |
| 56 | + if ( !isset( $params['storyaction'] ) ) { |
57 | 57 | $this->dieUsageMsg( array( 'missingparam', 'storyaction' ) ); |
58 | 58 | } |
59 | 59 | |
60 | | - // TODO: test the actions after using them in the storyreview special page |
61 | 60 | $dbw = wfGetDB( DB_MASTER ); |
62 | | - |
| 61 | + |
63 | 62 | if ( $params['storyaction'] == 'delete' ) { |
64 | 63 | $dbw->delete( 'storyboard', array( 'story_id' => $dbw->escape( $params['storyid'] ) ) ); |
65 | 64 | } else { |
— | — | @@ -92,7 +91,7 @@ |
93 | 92 | 'story_image_hidden' => 1 |
94 | 93 | ); |
95 | 94 | break; |
96 | | - case 'showimage' : |
| 95 | + case 'unhideimage' : |
97 | 96 | $values = array( |
98 | 97 | 'story_image_hidden' => 0 |
99 | 98 | ); |
— | — | @@ -100,12 +99,20 @@ |
101 | 100 | case 'deleteimage' : |
102 | 101 | $values = array( |
103 | 102 | 'story_author_image' => '' |
104 | | - ); |
| 103 | + ); // TODO: should image file also be removed? |
105 | 104 | break; |
106 | 105 | } |
107 | 106 | |
108 | 107 | $dbw->update( 'storyboard', $values, $conds ); |
109 | 108 | } |
| 109 | + |
| 110 | + $result = array( |
| 111 | + 'action' => $params['storyaction'], |
| 112 | + 'id' => $params['storyid'], |
| 113 | + ); |
| 114 | + |
| 115 | + $this->getResult()->setIndexedTagName( $result, 'story' ); |
| 116 | + $this->getResult()->addValue( null, 'result', $result ); |
110 | 117 | } |
111 | 118 | |
112 | 119 | public function getAllowedParams() { |
— | — | @@ -120,7 +127,7 @@ |
121 | 128 | 'publish', |
122 | 129 | 'unpublish', |
123 | 130 | 'hideimage', |
124 | | - 'showimage', |
| 131 | + 'unhideimage', |
125 | 132 | 'deleteimage', |
126 | 133 | ) |
127 | 134 | ), |