front/help: implement help views

This commit is contained in:
rr- 2016-03-29 12:34:10 +02:00
parent 4a13933590
commit 55c5363edc
10 changed files with 480 additions and 3 deletions

9
static/css/help.css Normal file
View file

@ -0,0 +1,9 @@
#help {
width: 40em;
}
#help nav {
margin-bottom: 1.5em;
}
#help td {
padding-right: 1em;
}

View file

@ -0,0 +1,13 @@
<p>Szurubooru is an image board engine inspired by services such as Danbooru,
Gelbooru and Moebooru. Its name <a href='http://sjp.pwn.pl/sjp/;2527372'>has
its roots in Polish language and has onomatopeic meaning of scraping or
scrubbing</a>. It is pronounced as <em>shoorubooru</em>.</p>
<p><strong>Registration</strong></p>
<p>The e-mail you enter during account creation is only used to retrieve your
Gravatar and for password reminders. Only you can see it (well, except the
database staff&hellip; we won&rsquo;t spam your mailbox anyway).</p>
<p>Oh, and you can delete your account at any time. Posts you uploaded will
stay, unless some angry admin removes them.</p>

View file

@ -0,0 +1,30 @@
<p>Comments support Markdown syntax, extended by some handy tags:</p>
<table>
<tbody>
<tr>
<td><code>@426</code></td>
<td>links to post number 426</td>
</tr>
<tr>
<td><code>#Dragon_Ball</code></td>
<td>links to tag &ldquo;Dragon_Ball&rdquo;</td>
</tr>
<tr>
<td><code>+Pirate</code></td>
<td>links to user &ldquo;Pirate&rdquo;</td>
</tr>
<tr>
<td><code>~~new~~</code></td>
<td>adds strike-through</td>
</tr>
<tr>
<td><code>[spoiler]Lelouch survives[/spoiler]</td>
<td>marks text as spoiler and hides it</td>
</tr>
<tr>
<td><code>[sjis](´・ω・`)[/sjis]</td>
<td>adds SJIS art</td>
</tr>
</tbody>
</table>

View file

@ -0,0 +1,42 @@
<p>You can use your keyboard to navigate around the site. There are a few
shortcuts:</p>
<table>
<thead>
<tr>
<th>Hotkey</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>[Q]</code></td>
<td>Focus search field, if available</td>
</tr>
<tr>
<td><code>[A]</code> and <code>[D]</code></td>
<td>Go to newer/older page or post</td>
</tr>
<tr>
<td><code>[F]</code></td>
<td>Cycle post fit mode</td>
</tr>
<tr>
<td><code>[E]</code></td>
<td>Edit post</td>
</tr>
<tr>
<td><code>[P]</code></td>
<td>Focus first post in post list</td>
</tr>
</tbody>
</table>
<p>Additionally, each item in top navigation can be accessed using feature
called &ldquo;access keys&rdquo;. Pressing underlined letter while holding
Shfit or Alt+Shift (depending on your browser) will go to the desired page
(most browsers) or focus the link (IE).</p>

265
static/html/help-search.tpl Normal file
View file

@ -0,0 +1,265 @@
<table>
<thead>
<tr>
<th>Command</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href='/posts/query=Haruhi'><code>Haruhi</code></a></td>
<td>containing tag “Haruhi”</td>
</tr>
<tr>
<td><a href='/posts/query=-Kyon'><code>-Kyon</code></a></td>
<td>not containing tag “Kyon”</td>
</tr>
<tr>
<td><a href='/posts/query=uploader:David'><code>uploader:David</code></a></td>
<td>uploaded by user David</td>
</tr>
<tr>
<td><a href='/posts/query=comment:David'><code>comment:David</code></a></td>
<td>commented by David</td>
</tr>
<tr>
<td><a href='/posts/query=fav:David'><code>fav:David</code></a></td>
<td>favorited by David</td>
</tr>
<tr>
<td><a href='/posts/query=fav_count:4'><code>fav_count:4</code></a></td>
<td>favorited by exactly four users</td>
</tr>
<tr>
<td><a href='/posts/query=fav_count:4,5'><code>fav_count:4,5</code></a></td>
<td>favorited by four or five users</td>
</tr>
<tr>
<td><a href='/posts/query=fav_count:4..'><code>fav_count:4..</code></a></td>
<td>favorited by at least four users</td>
</tr>
<tr>
<td><a href='/posts/query=fav_count:..4'><code>fav_count:..4</code></a></td>
<td>favorited by at most four users</td>
</tr>
<tr>
<td><a href='/posts/query=fav_count:4..6'><code>fav_count:4..6</code></a></td>
<td>favorited by at least four, but no more than six users</td>
</tr>
<tr>
<td><a href='/posts/query=comment_count:3'><code>comment_count:3</code></a></td>
<td>having exactly three comments</td>
</tr>
<tr>
<td><a href='/posts/query=score:4'><code>score:4</code></a></td>
<td>having score of 4</td>
</tr>
<tr>
<td><a href='/posts/query=tag_count:7'><code>tag_count:7</code></a></td>
<td>tagged with exactly seven tags</td>
</tr>
<tr>
<td><a href='/posts/query=note_count:1..'><code>note_count:1..</code></a></td>
<td>having at least one post note</td>
</tr>
<tr>
<td><a href='/posts/query=feature_count:1..'><code>feature_count:1..</code></a></td>
<td>having been featured at least once</td>
</tr>
<tr>
<td><a href='/posts/query=date:today'><code>date:today</code></a></td>
<td>posted today</td>
</tr>
<tr>
<td><a href='/posts/query=date:yesterday'><code>date:yesterday</code></a></td>
<td>posted yesterday</td>
</tr>
<tr>
<td><a href='/posts/query=date:2000'><code>date:2000</code></a></td>
<td>posted in year 2000</td>
</tr>
<tr>
<td><a href='/posts/query=date:2000-01'><code>date:2000-01</code></a></td>
<td>posted in January, 2000</td>
</tr>
<tr>
<td><a href='/posts/query=date:2000-01-01'><code>date:2000-01-01</code></a></td>
<td>posted on January 1st, 2000</td>
</tr>
<tr>
<td><a href='/posts/query=id:1'><code>id:1</code></a></td>
<td>having specific post ID</td>
</tr>
<tr>
<td><a href='/posts/query=name:hash'><code>name:<em>hash</em></code></a></td>
<td>having specific post name (hash in full URLs)</td>
</tr>
<tr>
<td><a href='/posts/query=file_size:100..'><code>file_size:100..</code></a></td>
<td>having at least 100 bytes</td>
</tr>
<tr>
<td><a href='/posts/query=image_width:100..'><code>image_width:100..</code></a></td>
<td>being at least 100 pixels wide</td>
</tr>
<tr>
<td><a href='/posts/query=image_height:100..'><code>image_height:100..</code></a></td>
<td>being at least 100 pixels tall</td>
</tr>
<tr>
<td><a href='/posts/query=image_area:10000..'><code>image_area:10000..</code></a></td>
<td>having at least 10000 pixels</td>
</tr>
<tr>
<td><a href='/posts/query=type:image'><code>type:image</code></a></td>
<td>only image posts</td>
</tr>
<tr>
<td><a href='/posts/query=type:flash'><code>type:flash</code></a></td>
<td>only Flash posts</td>
</tr>
<tr>
<td><a href='/posts/query=type:youtube'><code>type:youtube</code></a></td>
<td>only Youtube posts</td>
</tr>
<tr>
<td><a href='/posts/query=type:video'><code>type:video</code></a></td>
<td>only video posts</td>
</tr>
<tr>
<td><a href='/posts/query=special:liked'><code>special:liked</code></a></td>
<td>posts liked by currently logged in user</td>
</tr>
<tr>
<td><a href='/posts/query=special:disliked'><code>special:disliked</code></a></td>
<td>posts disliked by currently logged in user</td>
</tr>
<tr>
<td><a href='/posts/query=special:fav'><code>special:fav</code></a></td>
<td>posts added to favorites by currently logged in user</td>
</tr>
<tr>
<td><a href='/posts/query=special:tumbleweed'><code>special:tumbleweed</code></a></td>
<td>posts with score of 0, without comments and without favorites</td>
</tr>
</tbody>
</table>
<p>Most of the commands support ranged and composites values, e.g.
<code>id:<em>number</em></code> operator supports respectively
<a href='/posts/query=id:5..7'><code>id:5..7</code></a> and
<a href='/posts/query=id:5,10,15'><code>id:5,10,15</code></a>.
You can combine tags and negate any of them for interesting results.
<a href='/posts/query=sea -fav_count:..8 type:flash uploader:Pirate'><code>sea -fav_count:8.. type:swf uploader:Pirate</code></a>
will show you flash files tagged as sea, that were liked by seven people at
most, uploaded by user Pirate.</p>
<p>All of the above can be sorted using additional tag in form of
<code>order:<em>keyword</em></code>:</p>
<table>
<thead>
<tr>
<th>Command</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href='/posts/query=order:random'><code>order:random</code></a></td>
<td>as random as it can get</td>
</tr>
<tr>
<td><a href='/posts/query=order:id'><code>order:id</code></a></td>
<td>highest to lowest post ID (default browse view)</td>
</tr>
<tr>
<td><a href='/posts/query=order:creation_date'><code>order:creation_date</code></a></td>
<td>newest to oldest (pretty much same as above)</td>
</tr>
<tr>
<td><a href='/posts/query=-order:creation_date'><code>-order:creation_date</code></a></td>
<td>oldest to newest</td>
</tr>
<tr>
<td><a href='/posts/query=order:creation_date,asc'><code>order:creation_date,asc</code></a></td>
<td>oldest to newest (ascending order, default = descending)</td>
</tr>
<tr>
<td><a href='/posts/query=order:edit_date'><code>order:edit_date</code></a></td>
<td>like <code>creation_date</code>, only looks at last edit time</td>
</tr>
<tr>
<td><a href='/posts/query=order:score'><code>order:score</code></a></td>
<td>highest scored</td>
</tr>
<tr>
<td><a href='/posts/query=order:file_size'><code>order:file_size</code></a></td>
<td>largest files first</td>
</tr>
<tr>
<td><a href='/posts/query=order:image_width'><code>order:image_width</code></a></td>
<td>widest images first</td>
</tr>
<tr>
<td><a href='/posts/query=order:image_height'><code>order:image_height</code></a></td>
<td>tallest images first</td>
</tr>
<tr>
<td><a href='/posts/query=order:image_area'><code>order:image_area</code></a></td>
<td>largest images first</td>
</tr>
<tr>
<td><a href='/posts/query=order:tag_count'><code>order:tag_count</code></a></td>
<td>with most tags</td>
</tr>
<tr>
<td><a href='/posts/query=order:fav_count'><code>order:fav_count</code></a></td>
<td>loved by most</td>
</tr>
<tr>
<td><a href='/posts/query=order:comment_count'><code>order:comment_count</code></a></td>
<td>most commented first</td>
</tr>
<tr>
<td><a href='/posts/query=order:fav_date'><code>order:fav_date</code></a></td>
<td>recently added to favorites</td>
</tr>
<tr>
<td><a href='/posts/query=order:comment_date'><code>order:comment_date</code></a></td>
<td>recently commented</td>
</tr>
<tr>
<td><a href='/posts/query=order:feature_date'><code>order:feature_date</code></a></td>
<td>recently featured</td>
</tr>
<tr>
<td><a href='/posts/query=order:feature_count'><code>order:feature_count</code></a></td>
<td>most often featured</td>
</tr>
</tbody>
</table>
<p>As shown with <a
href='/posts/query=-order:creation_date'><code>-order:creation_date</code></a>,
any of them can be reversed in the same way as negating other tags: by placing
a dash before the tag.</p>

51
static/html/help-tos.tpl Normal file
View file

@ -0,0 +1,51 @@
<p>By accessing {{ name }} (&ldquo;Site&rdquo;) you agree to the following
Terms of Service. If you do not agree to these terms, then please do not access
the Site.</p>
<ul>
<li>The Site is presented to you AS IS, without any warranty, express or
implied. You will not hold the Site or its staff members liable for damages
caused by the use of the site.</li>
<li>The Site reserves the right to delete or modify your account, or any
content you have posted to the site.</li>
<li>The Site reserves the right to change these Terms of Service without
prior notice.</li>
<li>If you are a minor, then you will not use the Site.</li>
<li>You are using the Site only for personal use.</li>
<li>You will not spam, troll or offend anyone.</li>
<li>You accept that the Site is not liable for any content that you may
stumble upon.</li>
</ul>
<p id='section-prohibited-content'><strong>Prohibited content</strong></p>
<ul>
<li>Child pornography: any photograph or photorealistic drawing or movie
that depicts children in a sexual manner. This includes nudity, explicit
sex, implied sex, or sexually persuasive positions.</li>
<li>Bestiality: any photograph or photorealistic drawing or movie that
depicts humans having sex (either explicit or implied) with other non-human
animals.</li>
<li>Any depiction of extreme mutilation, extreme bodily distension,
feces.</li>
<li>Personal images: any image that is suspected to be uploaded for
personal use. This includes, but is not limited to, avatars and forum
signatures.</li>
</ul>
<p id='section-privacy-policy'><strong>Privacy policy</strong></p>
<p>The Site will not disclose the IP address or email address of any user
except to the staff.</p>
<p>Posts, comments, favorites, ratings and other actions linked to your account
will be stored in the Site&rsquo;s database. The &ldquo;Upload
anonymously&rdquo; option allows you to post content without linking it to your
account&nbsp;&ndash; meaning your nickname will not be stored in the database
nor shown in the &ldquo;Uploader&rdquo; field.</p>
<p>Cookies are used to store your session data in order to keep you logged in
and personalize your web experience.</p>

13
static/html/help.tpl Normal file
View file

@ -0,0 +1,13 @@
<div class='content-wrapper' id='help'>
<nav class='text-nav'><!--
--><ul><!--
--><li data-name='about'><a href='/help/about'>About</a></li><!--
--><li data-name='keyboard'><a href='/help/keyboard'>Keyboard</a></li><!--
--><li data-name='search'><a href='/help/search'>Search syntax</a></li><!--
--><li data-name='comments'><a href='/help/comments'>Comments</a></li><!--
--><li data-name='tos'><a href='/help/tos'>Terms of service</a></li><!--
--></ul><!--
--></nav>
<div class='content'>{{{ this.content }}}</div>
</div>

View file

@ -1,12 +1,14 @@
'use strict';
class HelpController {
constructor(topNavigationController) {
constructor(topNavigationController, helpView) {
this.topNavigationController = topNavigationController;
this.helpView = helpView;
}
showHelpRoute() {
showHelpRoute(section) {
this.topNavigationController.activate('help');
this.helpView.render(section);
}
}

View file

@ -4,6 +4,7 @@
// - import objects -
// ------------------
const Api = require('./api.js');
const HelpView = require('./views/help_view.js');
const LoginView = require('./views/login_view.js');
const RegistrationView = require('./views/registration_view.js');
const TopNavigationView = require('./views/top_navigation_view.js');
@ -25,6 +26,7 @@ const TagsController = require('./controllers/tags_controller.js');
const api = new Api();
const topNavigationView = new TopNavigationView();
const helpView = new HelpView();
const loginView = new LoginView();
const registrationView = new RegistrationView();
@ -41,7 +43,7 @@ const usersController = new UsersController(
topNavigationController,
authController,
registrationView);
const helpController = new HelpController(topNavigationController);
const helpController = new HelpController(topNavigationController, helpView);
const commentsController = new CommentsController(topNavigationController);
const historyController = new HistoryController(topNavigationController);
const tagsController = new TagsController(topNavigationController);
@ -78,6 +80,12 @@ page('/tags', () => { tagsController.listTagsRoute(); });
page('/comments', () => { commentsController.listCommentsRoute(); });
page('/login', () => { authController.loginRoute(); });
page('/logout', () => { authController.logoutRoute(); });
page(
'/help/:section',
(ctx, next) => {
helpController.showHelpRoute(ctx.params.section);
});
page('/help', () => { helpController.showHelpRoute(); });
page('*', () => { homeController.notFoundRoute(); });

View file

@ -0,0 +1,44 @@
'use strict';
const config = require('../config.js');
const BaseView = require('./base_view.js');
class HelpView extends BaseView {
constructor() {
super();
this.template = this.getTemplate('help-template');
this.sectionTemplates = {};
const sectionKeys = ['about', 'keyboard', 'search', 'comments', 'tos'];
for (let section of sectionKeys) {
const templateName = 'help-' + section + '-template';
this.sectionTemplates[section] = this.getTemplate(templateName);
}
}
render(section) {
if (!section) {
section = 'about';
}
if (!(section in this.sectionTemplates)) {
this.showView('');
return;
}
const content = this.sectionTemplates[section]({
'name': config.basic.name,
});
this.showView(this.template({'content': content}));
const allItemsSelector = '#content-holder [data-name]';
for (let item of document.querySelectorAll(allItemsSelector)) {
if (item.getAttribute('data-name') === section) {
item.className = 'active';
} else {
item.className = '';
}
}
}
}
module.exports = HelpView;