diff options
| author | Benjamin Southall <applemansigloo@gmail.com> | 2017-09-03 22:19:32 +0900 |
|---|---|---|
| committer | Benjamin Southall <applemansigloo@gmail.com> | 2017-09-03 22:19:32 +0900 |
| commit | 7f8c54249dea60f624e3f90b6c29adbd1207781b (patch) | |
| tree | 3cf14b57fbaa851a624a97606e7baf0c961118a3 /templates/themes | |
| parent | 8211c01d84b580abcbb57c3012f39020f1522063 (diff) | |
Add staff application theme, calendar theme and ukko4 theme
Diffstat (limited to 'templates/themes')
| -rw-r--r-- | templates/themes/calendar/calendar.html | 191 | ||||
| -rw-r--r-- | templates/themes/calendar/calendarpost.php | 53 | ||||
| -rw-r--r-- | templates/themes/calendar/info.php | 36 | ||||
| -rw-r--r-- | templates/themes/calendar/theme.php | 40 | ||||
| -rw-r--r-- | templates/themes/calendar/thumb.png | bin | 0 -> 7872 bytes | |||
| -rw-r--r-- | templates/themes/staffapplication/info.php | 36 | ||||
| -rw-r--r-- | templates/themes/staffapplication/staffapplication.html | 80 | ||||
| -rw-r--r-- | templates/themes/staffapplication/staffapplicationpost.php | 54 | ||||
| -rw-r--r-- | templates/themes/staffapplication/theme.php | 40 | ||||
| -rw-r--r-- | templates/themes/staffapplication/thumb.png | bin | 0 -> 7872 bytes | |||
| -rw-r--r-- | templates/themes/ukko4/info.php | 55 | ||||
| -rw-r--r-- | templates/themes/ukko4/theme.php | 162 | ||||
| -rw-r--r-- | templates/themes/ukko4/thumb.png | bin | 0 -> 13085 bytes | |||
| -rw-r--r-- | templates/themes/ukko4/ukko.js | 116 |
14 files changed, 863 insertions, 0 deletions
diff --git a/templates/themes/calendar/calendar.html b/templates/themes/calendar/calendar.html new file mode 100644 index 00000000..47b53eae --- /dev/null +++ b/templates/themes/calendar/calendar.html @@ -0,0 +1,191 @@ +<!doctype html> +<html> +<head> + <link rel="stylesheet" media="screen" href="/stylesheets/style.css"> + <meta charset="utf-8"> + {% if config.meta_keywords %}<meta name="keywords" content="{{ config.meta_keywords }}">{% endif %} + <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes"> + <link rel='stylesheet' href='/stylesheets/fullcalendar.min.css' /> + <script type='text/javascript'> + var active_page = "news"; + </script> + <title>{{ settings.title }}</title> + {% include 'header.html' %} + <script src='/js/moment.min.js'></script> + <script src='/js/fullcalendar.min.js'></script> +</head> +<body class="8chan vichan {% if mod %}is-moderator{% else %}is-not-moderator{% endif %}" data-stylesheet="{% if config.default_stylesheet.1 != '' %}{{ config.default_stylesheet.1 }}{% else %}default{% endif %}"> + <div class="bar top"> + {{ boardlist.top }} + </div> + <header> + <h1 class="glitch" data-text="{{ settings.title }}"> {{ settings.title }}</h1> + <div class="subtitle">{{ settings.subtitle }}</div> + </header> + <div class="ban"> + <div id='calendar'></div> + </div> + + <hr/> + <footer> + <p class="unimportant" style="margin-top:20px;text-align:center;">- <a href="http://tinyboard.org/">Tinyboard</a> + + <a href='https://int.vichan.net/devel/'>vichan</a> + + <a href='https://github.com/lainchan/lainchan'>lainchan</a> {{ config.version }} - + <br><a href="http://tinyboard.org/">Tinyboard</a> Copyright © 2010-2014 Tinyboard Development Group + <br><a href="https://engine.vichan.net/">vichan</a> Copyright © 2012-2016 vichan-devel + <br><a href="https://github.com/lainchan/lainchan">lainchan</a> Copyright © 2014-2017 lainchan Administration</p> + </footer> + <div class="pages"></div> + <script type='text/javascript'> + $(document).ready(function() { + + var calendar = $('#calendar').fullCalendar({ + editable: true, + header: { + left: 'prev,next today', + center: 'title', + right: 'month,agendaWeek,agendaDay' + }, + + events: "calendarpost.php", + + eventRender: function(event, element, view) { + if (event.allDay === 'true') { + event.allDay = true; + } else { + event.allDay = false; + } + element.find('.fc-title').append("<br/>" + event.description); + element.css('background-color',event.color); + }, + selectable: true, + selectHelper: true, + select: function(start, end, allDay) { + var title = prompt('Event Title:'); + var description = prompt('Event Description:'); + var url = prompt("Event URL"); + var color = prompt("Event Color"); + var starttime = prompt("Event Start Time"); + var endtime = prompt("Event End Time"); + if (title) { + var startmoment = moment(start); + var endmoment = moment(end); + var start = startmoment.format('YYYY-MM-DD HH:mm:ss'); + var end = endmoment.format('YYYY-MM-DD HH:mm:ss'); + if (starttime && endtime){ + var starttimemoment = moment(starttime,'HH:mm'); + var endtimemoment = moment(endtime,'HH:mm'); + startmoment.hour(starttimemoment.hour()); + startmoment.minute(starttimemoment.minute()); + endmoment.hour(endtimemoment.hour()); + endmoment.minute(endtimemoment.minute()); + endmoment.subtract(1, "days"); + allday = false; + start = startmoment.format('YYYY-MM-DD HH:mm:ss'); + end = endmoment.format('YYYY-MM-DD HH:mm:ss'); + } + $.ajax({ + url: 'calendarpost.php', + data: 'type=add&title='+ title+'&description='+ description +'&start='+ start +'&end='+ end + '&url='+url+'&color='+color, + type: "POST", + success: function(json) { + alert('Added Successfully'); + } + }); + calendar.fullCalendar('renderEvent', + { + title: title, + description: description, + start: start, + end: end, + allDay: allDay, + url: url, + color:color, + }, + true + ); + } + calendar.fullCalendar('unselect'); + }, + + editable: true, + eventDrop: function(event, delta) { + var startmoment = moment(start); + var endmoment = moment(end); + var start = startmoment.format('YYYY-MM-DD HH:mm:ss'); + var end = endmoment.format('YYYY-MM-DD HH:mm:ss'); + var starttime = prompt("Event Start Time"); + var endtime = prompt("Event End Time"); + if (starttime && endtime){ + var starttimemoment = moment(starttime,'HH:mm'); + var endtimemoment = moment(endtime,'HH:mm'); + startmoment.hour(starttimemoment.hour()); + startmoment.minute(starttimemoment.minute()); + endmoment.hour(endtimemoment.hour()); + endmoment.minute(endtimemoment.minute()); + allday = false; + endmoment.subtract(1, "days"); + start = startmoment.format('YYYY-MM-DD HH:mm:ss'); + end = endmoment.format('YYYY-MM-DD HH:mm:ss'); + } + $.ajax({ + url: 'calendarpost.php', + data: 'type=update&title='+ event.title+'&description='+ event.description + '&start='+ start +'&end='+ end +'&id='+ event.id , + type: "POST", + success: function(json) { + alert("Updated Successfully"); + } + }); + }, + eventClick: function(event) { + var decision = confirm("Do you really want to do that?"); + if (decision) { + $.ajax({ + type: "POST", + url: 'calendarpost.php', + data: "type=delete&id=" + event.id, + success: function(json) { + $('#calendar').fullCalendar('removeEvents', event.id); + alert("Updated Successfully");} + }); + + } + }, + eventResize: function(event) { + var startmoment = moment(start); + var endmoment = moment(end); + var start = moment(start).format('YYYY-MM-DD HH:mm:ss'); + var end = moment(end).format('YYYY-MM-DD HH:mm:ss'); + var starttime = prompt("Event Start Time"); + var endtime = prompt("Event End Time"); + if (starttime && endtime){ + var starttimemoment = moment(starttime,'HH:mm'); + var endtimemoment = moment(endtime,'HH:mm'); + startmoment.hour(starttimemoment.hour()); + startmoment.minute(starttimemoment.minute()); + endmoment.hour(endtimemoment.hour()); + endmoment.minute(endtimemoment.minute()); + allday = false; + endmoment.subtract(1, "days"); + start = startmoment.format('YYYY-MM-DD HH:mm:ss'); + end = endmoment.format('YYYY-MM-DD HH:mm:ss'); + } + $.ajax({ + url: 'calendarpost.php', + data: 'type=update&title='+ event.title+ '&description='+ event.description + '&start='+ start +'&end='+ end +'&id='+ event.id , + type: "POST", + success: function(json) { + alert("Updated Successfully"); + } + }); + } + + }); + + }); + </script> + <script type="text/javascript">{% raw %} + ready(); + {% endraw %}</script> +</body> +</html> diff --git a/templates/themes/calendar/calendarpost.php b/templates/themes/calendar/calendarpost.php new file mode 100644 index 00000000..a36e080c --- /dev/null +++ b/templates/themes/calendar/calendarpost.php @@ -0,0 +1,53 @@ +<?php +require '/var/www/html/inc/functions.php'; + +$method = $_SERVER['REQUEST_METHOD']; + if ($method == 'POST') { + // Method is POST + $type = $_POST['type']; + switch ($type) { + case "add": + $title = $_POST['title']; + $description = $_POST['description']; + $start = $_POST['start']; + $end = $_POST['end']; + $url = $_POST['url']; + $color = $_POST['color']; + $query = prepare("INSERT INTO calendar_events (title, description, start, end,url,color) VALUES (:title,:description, :start, :end,:url, :color )"); + $query->bindValue(':title', $title); + $query->bindValue(':description', $description); + $query->bindValue(':start', $start); + $query->bindValue(':end', $end); + $query->bindValue(':url', $url); + $query->bindValue(':color', $color); + $query->execute() or error(db_error($query)); + break; + case "delete": + $id = $_POST['id']; + $query = query("DELETE from calendar_events WHERE id = :id") or error(db_error()); + break; + case "update": + $id = $_POST['id']; + $title = $_POST['title']; + $description = $_POST['description']; + $start = $_POST['start']; + $end = $_POST['end']; + $query = prepare(" UPDATE calendar_events SET title = :title, description = :description, start = :start, end = :end, url = :url, color =:color WHERE id = :id"); + $query->bindValue(':id', $id); + $query->bindValue(':title', $title); + $query->bindValue(':description', $description); + $query->bindValue(':start', $start); + $query->bindValue(':end', $end); + $query->bindValue(':url', $url); + $query->bindValue(':color', $color); + $query->execute() or error(db_error($query)); + break; + default: + } + } elseif ($method == 'GET') { + // Method is GET + $query = query("SELECT * FROM calendar_events ORDER BY id") or error(db_error()); + echo json_encode($query->fetchAll(PDO::FETCH_ASSOC)); + } + +?> diff --git a/templates/themes/calendar/info.php b/templates/themes/calendar/info.php new file mode 100644 index 00000000..0687a26d --- /dev/null +++ b/templates/themes/calendar/info.php @@ -0,0 +1,36 @@ +<?php + $theme = Array(); + + // Theme name + $theme['name'] = 'Calendar'; + // Description (you can use Tinyboard markup here) + $theme['description'] = 'Calendar theme.'; + $theme['version'] = 'v0.0.1'; + + // Theme configuration + $theme['config'] = Array(); + + $theme['config'][] = Array( + 'title' => 'Site title', + 'name' => 'title', + 'type' => 'text' + ); + + $theme['config'][] = Array( + 'title' => 'Slogan', + 'name' => 'subtitle', + 'type' => 'text', + 'comment' => '(optional)' + ); + + $theme['config'][] = Array( + 'title' => 'File', + 'name' => 'file', + 'type' => 'text', + 'default' => $config['file_index'], + 'comment' => '(eg. "index.html")' + ); + + // Unique function name for building everything + $theme['build_function'] = 'calendar_build'; + diff --git a/templates/themes/calendar/theme.php b/templates/themes/calendar/theme.php new file mode 100644 index 00000000..8e9d32db --- /dev/null +++ b/templates/themes/calendar/theme.php @@ -0,0 +1,40 @@ +<?php + require 'info.php'; + + function calendar_build($action, $settings, $board) { + // Possible values for $action: + // - all (rebuild everything, initialization) + // - news (news has been updated) + // - boards (board list changed) + + Calendar::build($action, $settings); + } + + // Wrap functions in a class so they don't interfere with normal Tinyboard operations + class Calendar { + public static function build($action, $settings) { + global $config; + + if ($action == 'all' || $action == 'news') + file_write($config['dir']['home'] . $settings['file'], Calendar::htmlpage($settings)); + file_write($config['dir']['home'] . "calendarpost.php", Calendar::phppage($settings)); + } + + // Build staff application page + public static function htmlpage($settings) { + global $config; + + return Element('themes/calendar/calendar.html', Array( + 'settings' => $settings, + 'config' => $config, + 'boardlist' => createBoardlist() + )); + } + public static function phppage($settings) { + global $config; + $page = file_get_contents('templates/themes/calendar/calendarpost.php'); + return $page; + } + }; + +?> diff --git a/templates/themes/calendar/thumb.png b/templates/themes/calendar/thumb.png Binary files differnew file mode 100644 index 00000000..d0c3c771 --- /dev/null +++ b/templates/themes/calendar/thumb.png diff --git a/templates/themes/staffapplication/info.php b/templates/themes/staffapplication/info.php new file mode 100644 index 00000000..a8093093 --- /dev/null +++ b/templates/themes/staffapplication/info.php @@ -0,0 +1,36 @@ +<?php + $theme = Array(); + + // Theme name + $theme['name'] = 'StaffApplication'; + // Description (you can use Tinyboard markup here) + $theme['description'] = 'Staff Application theme.'; + $theme['version'] = 'v0.0.1'; + + // Theme configuration + $theme['config'] = Array(); + + $theme['config'][] = Array( + 'title' => 'Site title', + 'name' => 'title', + 'type' => 'text' + ); + + $theme['config'][] = Array( + 'title' => 'Slogan', + 'name' => 'subtitle', + 'type' => 'text', + 'comment' => '(optional)' + ); + + $theme['config'][] = Array( + 'title' => 'File', + 'name' => 'file', + 'type' => 'text', + 'default' => $config['file_index'], + 'comment' => '(eg. "index.html")' + ); + + // Unique function name for building everything + $theme['build_function'] = 'staffapplication_build'; + diff --git a/templates/themes/staffapplication/staffapplication.html b/templates/themes/staffapplication/staffapplication.html new file mode 100644 index 00000000..9ff98802 --- /dev/null +++ b/templates/themes/staffapplication/staffapplication.html @@ -0,0 +1,80 @@ +{% filter remove_whitespace %} +<!doctype html> +<html> +<head> + <link rel="stylesheet" media="screen" href="/stylesheets/style.css"> + <meta charset="utf-8"> + {% if config.meta_keywords %}<meta name="keywords" content="{{ config.meta_keywords }}">{% endif %} + <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes"> + <script type='text/javascript'> + var active_page = "news"; + </script> + <title>{{ settings.title }}</title> + {% include 'header.html' %} +</head> +<body class="8chan vichan {% if mod %}is-moderator{% else %}is-not-moderator{% endif %}" data-stylesheet="{% if config.default_stylesheet.1 != '' %}{{ config.default_stylesheet.1 }}{% else %}default{% endif %}"> + <div class="bar top"> + {{ boardlist.top }} + </div> + <header> + <h1 class="glitch" data-text="{{ settings.title }}"> {{ settings.title }}</h1> + <div class="subtitle">{{ settings.subtitle }}</div> + </header> + <center> + <img src="static/lain_is_cute_datass_small_teal.png" alt="mascot"/> + </center> + <div class="ban"> + <p> + Please use to the form below to apply to be staff.</br> + If you don't want to use this form you can also email admin@lainchan.org or ask in #questions on the Lainchan IRC channel. + In the rest of your application section, please specify the following information: </br> + Do you have to specify all the requested information below ? </br> + No of course not, but the more you specify the more likely your application will be approved, because applications + that demostrate that you can put effort in things, tell us that you can be bothered putting effort into things.</br> + What position you wanted to apply for ? E.g. Chan staff ? IRC staff ? Sysadmin ? Developer ? All of the above ? + None of the above ? Special snowflake role invented just for you ?</br> + Your reasons for applying ? </br> + Your existing qualifications for the position </br> + A summary of your strengths, weaknesses and interesting points / quirks </br> + If chan staff , then please specify which boards you are interested in and your experience with their subject matter. + </br> + Things to not include on your application. </br> + 1. NSFW pictures </br> + 2. Anything that is against the rules on the Rules page.</br> + 3. Short stories about ducks and ribbons and that guy Jimmy and other off topic things.</br> + 4. Your entire life story. </br> + 5. Your passport number or SSN and / or other identifying information. </br> + 6. Your rant about XYZ and how much all ABC need to suffer DEF because of it. </br> + </p> + <form action="staffapplication.php" method="post"> + <p><label for="name">Name: </label><input type="text" name="name" size="50"></p> + <p><label for="contactmethod">Preferred Contact Method: </label><select name="contactmethod"> + <option value="email" selected>Email</option> + <option value="irc">IRC</option> + <option value="chan">Lainchan</option> + </select></p> + <p><label for="email">Email: </label><input type="email" name="email" size="50"></p> + <p> + <label for="application">The rest of your application.</label><textarea name="application" rows="30" cols="50"></textarea> + </p> + <p><label for="anitspam">Antispam: (What is Cyberpunk , answer in all CAPS, single word, no spaces) </label><input type="text" name="antispam" size="50"></p> + <input type="submit" value="Send"> + </form> + </div> + + <hr/> + <footer> + <p class="unimportant" style="margin-top:20px;text-align:center;">- <a href="http://tinyboard.org/">Tinyboard</a> + + <a href='https://int.vichan.net/devel/'>vichan</a> + + <a href='https://github.com/lainchan/lainchan'>lainchan</a> {{ config.version }} - + <br><a href="http://tinyboard.org/">Tinyboard</a> Copyright © 2010-2014 Tinyboard Development Group + <br><a href="https://engine.vichan.net/">vichan</a> Copyright © 2012-2016 vichan-devel + <br><a href="https://github.com/lainchan/lainchan">lainchan</a> Copyright © 2014-2017 lainchan Administration</p> + </footer> + <div class="pages"></div> + <script type="text/javascript">{% raw %} + ready(); + {% endraw %}</script> +</body> +</html> +{% endfilter %} diff --git a/templates/themes/staffapplication/staffapplicationpost.php b/templates/themes/staffapplication/staffapplicationpost.php new file mode 100644 index 00000000..0e1b14ca --- /dev/null +++ b/templates/themes/staffapplication/staffapplicationpost.php @@ -0,0 +1,54 @@ +<?php +$name = $contactmethod = $email = $application = $antispam = $displaymessage = ""; +require '/var/www/html/inc/functions.php'; +if (isset ($_POST["antispam"])){ + if ($_POST["antispam"] == "DUCK"){ + $namecheck = ! empty($_POST["name"]); + $contactmethodcheck = $_POST["contactmethod"] == "email"; + $emailcheck = ! empty($_POST["email"]); + $emailischecked = $contactmethodcheck ? $emailcheck : true; + + if ($emailischecked && $namecheck){ + $name = $_POST["name"]; + $contactmethod = $_POST["contactmethod"]; + $email = $_POST["email"]; + $application = $_POST["application"]; + $antispam = $_POST["antispam"]; + $to = "admin@lainchan.org"; + $subject = "Lainchan.org Staff Application for " . $name; + + $message = "Name: " . $name . "\r\n"; + $message .= "Contact method: " . $contactmethod . "\r\n"; + $message .= $application; + $message = wordwrap($message, 70, "\r\n"); + + $source = $emailcheck ? $email : $to; + $headers = 'From: ' . $source . "\r\n" . + 'Reply-To: ' . $source . "\r\n" . + 'X-Mailer: PHP/' . phpversion(); + $sent = mail($to, $subject, $message, $headers); + $sentmessage = $sent ? "was submitted successfully.</p>\r\n" : "was unable to be submitted.</p>\r\n"; + $displaymessage = "<p style=\"text-align:center;\"> Your staff application " . $sentmessage; + } + + } + else + { + $displaymessage = "<p style=\"text-align:center;\">ANTISPAM VALUE INCORRECT</p>\r\n"; + + } +} +else { +$displaymessage = "<p style=\"text-align:center;\">ANTISPAM NOT SET</p>\r\n"; +} +$displaymessage .= '<span style="text-align:center; display: block;" >[ <a href="https://lainchan.org/"> Return Home </a> ]</span>'; + +echo Element('page.html', array( + 'index' => $config['root'], + 'title' => _('Staff Application'), + 'config' => $config, + 'boardlist' => createBoardlist(isset($mod) ? $mod : false), + 'body' => $displaymessage, + ) + ); +?> diff --git a/templates/themes/staffapplication/theme.php b/templates/themes/staffapplication/theme.php new file mode 100644 index 00000000..a827a7f8 --- /dev/null +++ b/templates/themes/staffapplication/theme.php @@ -0,0 +1,40 @@ +<?php + require 'info.php'; + + function staffapplication_build($action, $settings, $board) { + // Possible values for $action: + // - all (rebuild everything, initialization) + // - news (news has been updated) + // - boards (board list changed) + + StaffApplication::build($action, $settings); + } + + // Wrap functions in a class so they don't interfere with normal Tinyboard operations + class StaffApplication { + public static function build($action, $settings) { + global $config; + + if ($action == 'all' || $action == 'news') + file_write($config['dir']['home'] . $settings['file'], StaffApplication::htmlpage($settings)); + file_write($config['dir']['home'] . "staffapplication.php", StaffApplication::phppage($settings)); + } + + // Build staff application page + public static function htmlpage($settings) { + global $config; + + return Element('themes/staffapplication/staffapplication.html', Array( + 'settings' => $settings, + 'config' => $config, + 'boardlist' => createBoardlist() + )); + } + public static function phppage($settings) { + global $config; + $page = file_get_contents('templates/themes/staffapplication/staffapplicationpost.php'); + return $page; + } + }; + +?> diff --git a/templates/themes/staffapplication/thumb.png b/templates/themes/staffapplication/thumb.png Binary files differnew file mode 100644 index 00000000..d0c3c771 --- /dev/null +++ b/templates/themes/staffapplication/thumb.png diff --git a/templates/themes/ukko4/info.php b/templates/themes/ukko4/info.php new file mode 100644 index 00000000..dbbf6da8 --- /dev/null +++ b/templates/themes/ukko4/info.php @@ -0,0 +1,55 @@ +<?php + $theme = array(); + + // Theme name + $theme['name'] = 'Overboard (Ukko) 4'; + // Description (you can use Tinyboard markup here) + $theme['description'] = 'Board with threads and messages from all boards'; + $theme['version'] = 'v0.2'; + + // Theme configuration + $theme['config'] = array(); + + $theme['config'][] = array( + 'title' => 'Board name', + 'name' => 'title', + 'type' => 'text', + 'default' => 'Ukko' + ); + $theme['config'][] = array( + 'title' => 'Board URI', + 'name' => 'uri', + 'type' => 'text', + 'default' => '*', + 'comment' => '(ukko for example)' + ); + $theme['config'][] = array( + 'title' => 'Subtitle', + 'name' => 'subtitle', + 'type' => 'text', + 'comment' => '(%s = thread limit. for example "%s freshly bumped threads")' + ); + $theme['config'][] = array( + 'title' => 'Excluded boards', + 'name' => 'exclude', + 'type' => 'text', + 'comment' => '(space seperated)' + ); + $theme['config'][] = array( + 'title' => 'Number of threads', + 'name' => 'thread_limit', + 'type' => 'text', + 'default' => '15', + ); + // Unique function name for building everything + $theme['build_function'] = 'ukko4_build'; + $theme['install_callback'] = 'ukko4_install'; + + if(!function_exists('ukko4_install')) { + function ukko4_install($settings) { + if (!file_exists($settings['uri'])) + @mkdir($settings['uri'], 0777) or error("Couldn't create " . $settings['uri'] . ". Check permissions.", true); + file_write($settings['uri'] . '/ukko.js', Element('themes/ukko/ukko.js', array())); + } + } + diff --git a/templates/themes/ukko4/theme.php b/templates/themes/ukko4/theme.php new file mode 100644 index 00000000..4511483e --- /dev/null +++ b/templates/themes/ukko4/theme.php @@ -0,0 +1,162 @@ +<?php + require 'info.php'; + + function ukko4_build($action, $settings) { + global $config; + + $ukko = new ukko(); + $ukko->settings = $settings; + + if (! ($action == 'all' || $action == 'post' || $action == 'post-thread' || $action == 'post-delete')) { + return; + } + + $action = generation_strategy('sb_ukko', array()); + + if ($action == 'delete') { + file_unlink($settings['uri'] . '/index.html'); + if ($config['api']['enabled']) { + $jsonFilename = $settings['uri'] . '/0.json'; + file_unlink($jsonFilename); + $jsonFilename = $settings['uri'] . '/catalog.json'; + file_unlink($jsonFilename); + $jsonFilename = $settings['uri'] . '/threads.json'; + file_unlink($jsonFilename); + } + } + elseif ($action == 'rebuild') { + file_write($settings['uri'] . '/index.html', $ukko->build()); + } + } + + class ukko4 { + public $settings; + public function build($mod = false) { + global $config; + $boards = listBoards(); + + $body = ''; + $overflow = array(); + $board = array( + 'dir' => $this->settings['uri'] . "/", + 'url' => $this->settings['uri'], + 'uri' => $this->settings['uri'], + 'name' => $this->settings['title'], + 'title' => sprintf($this->settings['subtitle'], $this->settings['thread_limit']) + ); + + $boardsforukko = array(); + $query = ''; + foreach($boards as &$_board) { + if(in_array($_board['uri'], explode(' ', $this->settings['exclude']))) + continue; + $query .= sprintf("SELECT *, '%s' AS `board` FROM ``posts_%s`` WHERE `thread` IS NULL UNION ALL ", $_board['uri'], $_board['uri']); + array_push($boardsforukko,$_board); + } + $query = preg_replace('/UNION ALL $/', 'ORDER BY `bump` DESC', $query); + $query = query($query) or error(db_error()); + + $count = 0; + $threads = array(); + if ($config['api']['enabled']) { + $apithreads = array(); + } + while($post = $query->fetch()) { + + if(!isset($threads[$post['board']])) { + $threads[$post['board']] = 1; + } else { + $threads[$post['board']] += 1; + } + + if($count < $this->settings['thread_limit']) { + openBoard($post['board']); + $thread = new Thread($post, $mod ? '?/' : $config['root'], $mod); + + $posts = prepare(sprintf("SELECT * FROM ``posts_%s`` WHERE `thread` = :id ORDER BY `sticky` DESC, `id` DESC LIMIT :limit", $post['board'])); + $posts->bindValue(':id', $post['id']); + $posts->bindValue(':limit', ($post['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview']), PDO::PARAM_INT); + $posts->execute() or error(db_error($posts)); + + $num_images = 0; + while ($po = $posts->fetch()) { + if ($po['files']) + $num_images++; + $post2 = new Post($po, $mod ? '?/' : $config['root'], $mod); + $thread->add($post2); + + } + if ($posts->rowCount() == ($post['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview'])) { + $ct = prepare(sprintf("SELECT COUNT(`id`) as `num` FROM ``posts_%s`` WHERE `thread` = :thread UNION ALL SELECT COUNT(`id`) FROM ``posts_%s`` WHERE `files` IS NOT NULL AND `thread` = :thread", $post['board'], $post['board'])); + $ct->bindValue(':thread', $post['id'], PDO::PARAM_INT); + $ct->execute() or error(db_error($count)); + + $c = $ct->fetch(); + $thread->omitted = $c['num'] - ($post['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview']); + + $c = $ct->fetch(); + $thread->omitted_images = $c['num'] - $num_images; + } + + + $thread->posts = array_reverse($thread->posts); + $body .= '<h2><a href="' . $config['root'] . $post['board'] . '">/' . $post['board'] . '/</a></h2>'; + $body .= $thread->build(true); + if ($config['api']['enabled']) { + array_push($apithreads,$thread); + } + } else { + $page = 'index'; + if(floor($threads[$post['board']] / $config['threads_per_page']) > 0) { + $page = floor($threads[$post['board']] / $config['threads_per_page']) + 1; + } + $overflow[] = array('id' => $post['id'], 'board' => $post['board'], 'page' => $page . '.html'); + } + + $count += 1; + } + + $body .= '<script> var overflow = ' . json_encode($overflow) . '</script>'; + $body .= '<script type="text/javascript" src="/'.$this->settings['uri'].'/ukko.js"></script>'; + + // json api + if ($config['api']['enabled']) { + require_once __DIR__. '/../../../inc/api.php'; + $api = new Api(); + $jsonFilename = $board['dir'] . '0.json'; + $json = json_encode($api->translatePage($apithreads)); + file_write($jsonFilename, $json); + + + $catalog = array(); + $catalog[0] = $apithreads; + + $json = json_encode($api->translateCatalog($catalog)); + $jsonFilename = $board['dir'] . 'catalog.json'; + file_write($jsonFilename, $json); + + $json = json_encode($api->translateCatalog($catalog, true)); + $jsonFilename = $board['dir'] . 'threads.json'; + file_write($jsonFilename, $json); + } + $antibot = null; + if (!$antibot) { + $antibot = create_antibot($board['uri']); + } + $antibot->reset(); + + return Element('index.html', array( + 'config' => $config, + 'board' => $board, + 'no_post_form' => $config['overboard_post_form'] ? false : true, + 'body' => $body, + 'mod' => $mod, + 'boardlist' => createBoardlist($mod), + 'boards' => $boardsforukko, + 'antibot' => $antibot ) + ); + } + + }; + +?> diff --git a/templates/themes/ukko4/thumb.png b/templates/themes/ukko4/thumb.png Binary files differnew file mode 100644 index 00000000..eb616ef7 --- /dev/null +++ b/templates/themes/ukko4/thumb.png diff --git a/templates/themes/ukko4/ukko.js b/templates/themes/ukko4/ukko.js new file mode 100644 index 00000000..b2668e0b --- /dev/null +++ b/templates/themes/ukko4/ukko.js @@ -0,0 +1,116 @@ +(function(){ + +var cache = new Array(), + thread = false, + loading = false, + ukkotimer = false; + +if (localStorage.hiddenboards === undefined) { + localStorage.hiddenboards = "{}"; +} + +// Load data from HTML5 localStorage +var hiddenboards = JSON.parse(localStorage.hiddenboards); + +var storeboards = function() { + localStorage.hiddenboards = JSON.stringify(hiddenboards); +}; + +$(document).ready(function() { + var addukkohide = function() { + var ukkohide = $('<a href="javascript:void(0);" class="unimportant ukkohide"></a>'); + var board = $(this).next().data("board"); + var hr = $("<hr />"); + + $(this).append(ukkohide); + $(this).append(hr); + + if (hiddenboards[board] !== true) { + ukkohide.html(_("(hide threads from this board)")); + hr.hide(); + } + else { + ukkohide.html(_("(show threads from this board)")); + $(this).next().hide(); + } + ukkohide.click(function() { + hiddenboards[board] = (hiddenboards[board] !== true); + if (hiddenboards[board] !== true) { + $('[data-board="'+board+'"]:not([data-cached="yes"])').show().prev(). + find('.ukkohide').html(_("(hide threads from this board)")). + parent().find('hr').hide(); + } + else { + $('[data-board="'+board+'"]:not([data-cached="yes"])').hide().prev(). + find('.ukkohide').html(_("(show threads from this board)")) + .parent().find('hr').show(); + } + storeboards(); + return false; + }); + + }; + $("h2").each(addukkohide); + + $('.pages').hide(); + var loadnext = function() { + if (overflow.length == 0) { + $('.pages').show().html(_("No more threads to display")); + } + while($(window).scrollTop() + $(window).height() + 1000 > $(document).height() && !loading && overflow.length > 0) { + var page = modRoot + overflow[0].board + '/' + overflow[0].page; + thread = $('div#thread_' + overflow[0].id + '[data-board="' + overflow[0].board + '"]'); + if (thread.length > 0 && thread.attr("data-cached") !== 'yes') { // already present + overflow.shift(); + continue; + } + + var boardheader = $('<h2><a href="/' + overflow[0].board + '/">/' + overflow[0].board + '/</a> </h2>'); + + if($.inArray(page, cache) != -1) { + if (thread.length > 0) { + $('div[id*="thread_"]').last().after(thread.attr('data-board', overflow[0].board).attr("data-cached", "no").css('display', 'block')); + boardheader.insertBefore(thread); + addukkohide.call(boardheader); + $(document).trigger('new_post', thread); + } + overflow.shift(); + } else { + loading = true; + $('.pages').show().html(_("Loading...")); + $.get(page, function(data) { + cache.push(page); + + $(data).find('div[id*="thread_"]').each(function() { + var checkout = $(this).attr('id').replace('thread_', ''); + if ($('div#thread_' + checkout + '[data-board="' + overflow[0].board + '"]').length == 0) { + $('form[name="postcontrols"]').prepend($(this).css('display', 'none').attr("data-cached", "yes").attr('data-board', overflow[0].board)); + } + }); + + thread = $('div#thread_' + overflow[0].id + '[data-board="' + overflow[0].board + '"][data-cached="yes"]'); + + if(thread.length > 0) { + $('div[id*="thread_"]').last().after(thread.attr('data-board', overflow[0].board).attr("data-cached", "no").css('display', 'block')); + boardheader.insertBefore(thread); + addukkohide.call(boardheader); + $(document).trigger('new_post', thread); + } + overflow.shift(); + + loading = false; + $('.pages').hide().html(""); + }); + break; + } + } + clearTimeout(ukkotimer); + ukkotimer = setTimeout(loadnext, 1000); + }; + + $(window).on('scroll', loadnext); + + ukkotimer = setTimeout(loadnext, 1000); +}); + +})(); |
