This commit is contained in:
flash 2015-05-05 03:47:58 +00:00
parent 5dcd2804a5
commit b67645738e
8 changed files with 209 additions and 44 deletions

View file

@ -25,7 +25,8 @@
"20150503", "20150503",
"20150503.1", "20150503.1",
"20150504", "20150504",
"20150504.1" "20150504.1",
"20150505"
] ]
@ -914,6 +915,23 @@
"change": "Add beginning parts of the warning systems." "change": "Add beginning parts of the warning systems."
} }
],
"20150505": [
{
"type": "UPD",
"change": "getWarnings() can now return all warnings when the first parameter is false."
},
{
"type": "ADD",
"change": "Added parallax effect to profile backgrounds."
},
{
"type": "ADD",
"change": "Added comments to the Yuuno JavaScript."
}
] ]
} }

View file

@ -919,12 +919,12 @@ class Users {
} }
// Get all warnings issued to a user (or all warnings a user issued) // Get all warnings issued to a user (or all warnings a user issued)
public static function getWarnings($uid, $iid = false) { public static function getWarnings($uid = 0, $iid = false) {
// Do the database query // Do the database query
$warnings = Database::fetch('warnings', true, [ $warnings = Database::fetch('warnings', true, ($uid ? [
($iid ? 'iid' : 'uid') => [$uid, '='] ($iid ? 'iid' : 'uid') => [$uid, '=']
]); ] : null));
// Return all the warnings // Return all the warnings
return $warnings; return $warnings;

View file

@ -8,7 +8,7 @@
namespace Sakura; namespace Sakura;
// Define Sakura version // Define Sakura version
define('SAKURA_VERSION', '20150504'); define('SAKURA_VERSION', '20150505');
define('SAKURA_VLABEL', 'Heliotrope'); define('SAKURA_VLABEL', 'Heliotrope');
define('SAKURA_VTYPE', 'Development'); define('SAKURA_VTYPE', 'Development');
define('SAKURA_COLOUR', '#DF73FF'); define('SAKURA_COLOUR', '#DF73FF');

View file

@ -11,7 +11,7 @@
</ul> </ul>
</div> </div>
{% else %} {% else %}
<div class="userBackground"></div> <div id="userBackground"></div>
<div class="content profile"> <div class="content profile">
<div class="{% if profile.profpage|length > 1 %}content-right {% endif %}content-column"> <div class="{% if profile.profpage|length > 1 %}content-right {% endif %}content-column">
<div style="text-align: center;"> <div style="text-align: center;">
@ -64,7 +64,7 @@
{% else %} {% else %}
{% if profile.warnings %} {% if profile.warnings %}
<h2 style="color: red; text-shadow: 0 0 7px #888; margin-top: 0;">Bad</h2> <h2 style="color: red; text-shadow: 0 0 7px #888; margin-top: 0;">Bad</h2>
<span style="font-size: 10px; line-height: 10px;">This user has <b>{{ profile.warnings|length }} warning{% if profile.warnings|length != 1 %}s{% endif %}</b>.<br />After 5 to 10 more warnings (depending on what they are for) this user may be permanently banned.</span> <span style="font-size: 10px; line-height: 10px;">This user has <b>{{ profile.warnings|length }} warning{% if profile.warnings|length != 1 %}s{% endif %}</b>.<br />After 5 to 10 warnings (depending on what they are for) this user may be permanently banned.</span>
{% else %} {% else %}
<h2 style="color: green; text-shadow: 0 0 7px #888; margin-top: 0;">Good</h2> <h2 style="color: green; text-shadow: 0 0 7px #888; margin-top: 0;">Good</h2>
{% endif %} {% endif %}
@ -76,5 +76,10 @@
</div> </div>
<div class="clear"></div> <div class="clear"></div>
</div> </div>
{% if profile.user.background_url %}
<script type="text/javascript">
initialiseParallax('userBackground');
</script>
{% endif %}
{% endif %} {% endif %}
{% include 'global/footer.tpl' %} {% include 'global/footer.tpl' %}

View file

@ -2,54 +2,78 @@
* Sakura Yuuno JavaScript * Sakura Yuuno JavaScript
*/ */
// Get or set cookies
function cookieData(action, name, data) { function cookieData(action, name, data) {
switch(action) { switch(action) {
case 'get': case 'get':
return (result = new RegExp('(^|; )' + encodeURIComponent(name) + '=([^;]*)').exec(document.cookie)) ? result[2] : ''; return (result = new RegExp('(^|; )' + encodeURIComponent(name) + '=([^;]*)').exec(document.cookie)) ? result[2] : '';
case 'set': case 'set':
document.cookie = name + '=' + data; document.cookie = name + '=' + data;
return; return;
default: default:
return; return;
} }
} }
// Toggling the menu on mobile devices
function mobileMenu(mode) { function mobileMenu(mode) {
// Assign the elements to variables
var ucpMenuBtn = document.getElementById('navMenuSite'); var ucpMenuBtn = document.getElementById('navMenuSite');
var navMenuBtn = document.getElementById('navMenuUser'); var navMenuBtn = document.getElementById('navMenuUser');
var mobMenuBtn = document.getElementById('mobileNavToggle'); var mobMenuBtn = document.getElementById('mobileNavToggle');
// Open or close the menus depending on the values
if(mode) { if(mode) {
// Alter the classes
ucpMenuBtn.className = ucpMenuBtn.className + ' menu-hid'; ucpMenuBtn.className = ucpMenuBtn.className + ' menu-hid';
navMenuBtn.className = navMenuBtn.className + ' menu-hid'; navMenuBtn.className = navMenuBtn.className + ' menu-hid';
// Update the button
mobMenuBtn.innerHTML = 'Close Menu'; mobMenuBtn.innerHTML = 'Close Menu';
mobMenuBtn.setAttribute('onclick', 'mobileMenu(false);'); mobMenuBtn.setAttribute('onclick', 'mobileMenu(false);');
} else { } else {
// Alter the classes
ucpMenuBtn.className = ucpMenuBtn.className.replace(' menu-hid', ''); ucpMenuBtn.className = ucpMenuBtn.className.replace(' menu-hid', '');
navMenuBtn.className = navMenuBtn.className.replace(' menu-hid', ''); navMenuBtn.className = navMenuBtn.className.replace(' menu-hid', '');
// Update the button
mobMenuBtn.innerHTML = 'Open Menu'; mobMenuBtn.innerHTML = 'Open Menu';
mobMenuBtn.setAttribute('onclick', 'mobileMenu(true);'); mobMenuBtn.setAttribute('onclick', 'mobileMenu(true);');
} }
} }
// Event watcher for the scroll-to-top button
window.onscroll = function() { window.onscroll = function() {
// Assign the gotop button to a variable
var gotop = document.getElementById('gotop'); var gotop = document.getElementById('gotop');
if(this.pageYOffset < 112) { // If the vertical offset of the page is below 112px (just below the header) keep the button hidden
if(gotop.getAttribute('class').indexOf('hidden') < 0) if(this.pageYOffset < 112) {
gotop.setAttribute('class', gotop.getAttribute('class') + ' hidden'); if(gotop.getAttribute('class').indexOf('hidden') < 0)
} else if(this.pageYOffset > 112) gotop.setAttribute('class', gotop.getAttribute('class') + ' hidden');
gotop.setAttribute('class', gotop.getAttribute('class').replace(' hidden', '')); } else if(this.pageYOffset > 112) // Else show it
gotop.setAttribute('class', gotop.getAttribute('class').replace(' hidden', ''));
}; };
// Get the current unix/epoch timestamp
function epochTime() { function epochTime() {
var time = Date.now();
time = time / 1000; return Math.floor(Date.now() / 1000);
return Math.floor(time);
} }
/* /*
@ -119,53 +143,78 @@ function notificationRequest() {
setTimeout(notificationRequest, 5000); setTimeout(notificationRequest, 5000);
}*/ }*/
// Donate page specific features
function donatePage(id) { function donatePage(id) {
// Get the featureBoxDesc elements
var featureBoxDesc = document.getElementsByClassName('featureBoxDesc'); var featureBoxDesc = document.getElementsByClassName('featureBoxDesc');
// If an id wasn't set assume that we're doing initialisation
if(!id) { if(!id) {
// Go over every element and add donateClosed to the end of the class
for(var i = 0; i < featureBoxDesc.length; i++) for(var i = 0; i < featureBoxDesc.length; i++)
featureBoxDesc[i].className = featureBoxDesc[i].className + ' donateClosed'; featureBoxDesc[i].className = featureBoxDesc[i].className + ' donateClosed';
// Then stop the execution of the function
return; return;
} }
// Get the second child of the featureBox (which is the description)
var featureBox = document.getElementById(id).children[1]; var featureBox = document.getElementById(id).children[1];
// Search for donateOpened in the class and if found...
if(featureBox.className.search('donateOpened') > 0) { if(featureBox.className.search('donateOpened') > 0) {
// replace it with nothing and add donateClosed to the class
featureBox.className = featureBox.className.replace(' donateOpened', ''); featureBox.className = featureBox.className.replace(' donateOpened', '');
featureBox.className = featureBox.className + ' donateClosed'; featureBox.className = featureBox.className + ' donateClosed';
return;
} else { } else {
// Else do the opposite of what was described above
featureBox.className = featureBox.className.replace(' donateClosed', ''); featureBox.className = featureBox.className.replace(' donateClosed', '');
featureBox.className = featureBox.className + ' donateOpened'; featureBox.className = featureBox.className + ' donateOpened';
return;
} }
return;
} }
// Removing all elements with a certain class
function removeClass(className) { function removeClass(className) {
// Get the elements
var objectCont = document.getElementsByClassName(className); var objectCont = document.getElementsByClassName(className);
// Use a while loop instead of a for loop (Array keys change) to remove each element
while(objectCont.length > 0) while(objectCont.length > 0)
objectCont[0].parentNode.removeChild(objectCont[0]); objectCont[0].parentNode.removeChild(objectCont[0]);
} }
// Removing an element by ID
function removeId(id) { function removeId(id) {
// Get the element
var objectCont = document.getElementById(id); var objectCont = document.getElementById(id);
// If the element exists use the parent node to remove it
if(typeof(objectCont) != "undefined" && objectCont !== null) if(typeof(objectCont) != "undefined" && objectCont !== null)
objectCont.parentNode.removeChild(objectCont); objectCont.parentNode.removeChild(objectCont);
} }
// Show the full-page busy window
function ajaxBusyView(show, message, type) { function ajaxBusyView(show, message, type) {
// Get elements
var busyCont = document.getElementById('ajaxBusy'); var busyCont = document.getElementById('ajaxBusy');
var busyStat = document.getElementById('ajaxStatus'); var busyStat = document.getElementById('ajaxStatus');
var busyAnim = document.getElementById('ajaxAnimate'); var busyAnim = document.getElementById('ajaxAnimate');
var pageContent = document.getElementById('contentwrapper'); var pageContent = document.getElementById('contentwrapper');
// Select the proper icon
switch(type) { switch(type) {
default: default:
@ -181,69 +230,106 @@ function ajaxBusyView(show, message, type) {
} }
// If requested to show the window build it
if(show) { if(show) {
// Make sure it doesn't exist already
if(busyCont == null) { if(busyCont == null) {
// Container
var createBusyCont = document.createElement('div'); var createBusyCont = document.createElement('div');
createBusyCont.className = 'ajax-busy'; createBusyCont.className = 'ajax-busy';
createBusyCont.setAttribute('id', 'ajaxBusy'); createBusyCont.setAttribute('id', 'ajaxBusy');
// Inner box
var createBusyInner = document.createElement('div'); var createBusyInner = document.createElement('div');
createBusyInner.className = 'ajax-inner'; createBusyInner.className = 'ajax-inner';
createBusyCont.appendChild(createBusyInner); createBusyCont.appendChild(createBusyInner);
// Action description
var createBusyMsg = document.createElement('h2'); var createBusyMsg = document.createElement('h2');
createBusyMsg.setAttribute('id', 'ajaxStatus'); createBusyMsg.setAttribute('id', 'ajaxStatus');
createBusyInner.appendChild(createBusyMsg); createBusyInner.appendChild(createBusyMsg);
// FontAwesome icon
var createBusySpin = document.createElement('div'); var createBusySpin = document.createElement('div');
createBusySpin.setAttribute('id', 'ajaxAnimate'); createBusySpin.setAttribute('id', 'ajaxAnimate');
createBusyInner.appendChild(createBusySpin); createBusyInner.appendChild(createBusySpin);
// Append the element to the actual page
pageContent.appendChild(createBusyCont); pageContent.appendChild(createBusyCont);
// Reassign the previously assigned variables
busyCont = document.getElementById('ajaxBusy'); busyCont = document.getElementById('ajaxBusy');
busyStat = document.getElementById('ajaxStatus'); busyStat = document.getElementById('ajaxStatus');
busyAnim = document.getElementById('ajaxAnimate'); busyAnim = document.getElementById('ajaxAnimate');
}
} // If the container already exists just continue and update the elements
// Alter the icon
busyAnim.className = busyAnimIco; busyAnim.className = busyAnimIco;
if(message == null) // Change the message
busyStat.innerHTML = 'Please wait'; busyStat.innerHTML = (message == null ? 'Unknown' : message)
else
busyStat.innerHTML = message; } else { // If show is false remove the element...
} else {
// ...but just do nothing if the container doesn't exist
if(busyCont != null) { if(busyCont != null) {
// Create the fadeout with a 10ms interval
var fadeOut = setInterval(function() { var fadeOut = setInterval(function() {
// Set an opacity if it doesn't exist yet
if(busyCont.style.opacity == null || busyCont.style.opacity == "") if(busyCont.style.opacity == null || busyCont.style.opacity == "")
busyCont.style.opacity = 1; busyCont.style.opacity = 1;
// If the value isn't 0 yet start subtract .1 from the opacity
if(busyCont.style.opacity > 0) { if(busyCont.style.opacity > 0) {
busyCont.style.opacity = busyCont.style.opacity - .1; busyCont.style.opacity = busyCont.style.opacity - .1;
} else {
} else { // When we've reached 0 remove the container element and clear the fadeout interval
removeId('ajaxBusy'); removeId('ajaxBusy');
clearInterval(fadeOut); clearInterval(fadeOut);
} }
}, 10); }, 10);
} }
} }
} }
// Making a post request using AJAX
function ajaxPost(url, data) { function ajaxPost(url, data) {
// Create a new XMLHttpRequest
var req = new XMLHttpRequest(); var req = new XMLHttpRequest();
// Open a post request
req.open("POST", url, false); req.open("POST", url, false);
// Set the request header to a form
req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
// Combine name and value with an = inbetween
var query = []; var query = [];
for(var i in data) for(var i in data)
query.push(encodeURIComponent(i) +"="+ encodeURIComponent(data[i])); query.push(encodeURIComponent(i) +"="+ encodeURIComponent(data[i]));
// Join the array and submit the request
req.send(query.join("&")); req.send(query.join("&"));
// If the HTTP resonse was 200 return the page
if(req.status === 200) if(req.status === 200)
return req.responseText; return req.responseText;
else else // Else return nothing
return ""; return "";
} }
// Quickly building a form for god knows what reason // Quickly building a form for god knows what reason
@ -347,3 +433,56 @@ function submitPost(formId, busyView, msg) {
return; return;
} }
// Initialising the element parallax functionality
function initialiseParallax(id) {
// Assign the element to a variable
var parallax = document.getElementById(id);
// Set proper position values
parallax.style.top = '-2.5px';
parallax.style.bottom = '-2.5px';
parallax.style.left = '-2.5px';
parallax.style.right = '-2.5px';
// Add the event listener to the body element
document.addEventListener("mousemove", function(e) {
// Alter the position of the parallaxed element
parallax.style.top = convertParallaxPositionValue(e.clientY, true, false) + 'px';
parallax.style.bottom = convertParallaxPositionValue(e.clientY, true, true) + 'px';
parallax.style.left = convertParallaxPositionValue(e.clientX, false, false) + 'px';
parallax.style.right = convertParallaxPositionValue(e.clientX, false, true) + 'px';
});
}
// Converting the position value of the mouseover to a pixel value
function convertParallaxPositionValue(pos, dir, neg) {
// Get the body element
var body = document.getElementsByTagName('body')[0];
// Get percentage of current position
var position = (pos / (dir ? body.clientHeight : body.clientWidth)) * 100;
// If someone decided to fuck with the inputs reset it to 0%
if(position < 0 || position > 100)
position = 0;
// Do the first maths
position = (position / (dir ? 25 : 20)) - 2.5;
// If the negative flag is set inverse the number
if(neg)
position = -position;
// Subtract another 2.5 to make the element not go all over the place
position = position - 2.5;
// Return the proper position value
return position;
}

View file

@ -31,6 +31,9 @@ RewriteRule ^news?/?$ news.php
RewriteRule ^news/([0-9]+)$ news.php?id=$1 RewriteRule ^news/([0-9]+)$ news.php?id=$1
RewriteRule ^news.xml$ news.php?xml RewriteRule ^news.xml$ news.php?xml
## Settings
RewriteRule ^settings?/?$ settings.php
## Members ## Members
RewriteRule ^members?/?$ members.php RewriteRule ^members?/?$ members.php
RewriteRule ^members/([a-z]+)?/?$ members.php?sort=$1 RewriteRule ^members/([a-z]+)?/?$ members.php?sort=$1

View file

@ -16,10 +16,10 @@ $renderData['page'] = [
'articleCount' => count($renderData['newsPosts']) 'articleCount' => count($renderData['newsPosts'])
]; ];
$renderData['stats'] = [ $renderData['stats'] = [
'userCount' => ($userCount = count($users = Users::getAllUsers(false))) .' user'. ($userCount == 1 ? '' : 's'), 'userCount' => ($_INDEX_USER_COUNT = count($_INDEX_USERS = Users::getAllUsers(false))) .' user'. ($_INDEX_USER_COUNT == 1 ? '' : 's'),
'newestUser' => max($users), 'newestUser' => ($_INDEX_NEWEST_USER = max($_INDEX_USERS)),
'lastRegDate' => ($lastRegDate = date_diff(date_create(date('Y-m-d', max($users)['regdate'])), date_create(date('Y-m-d')))->format('%a')) .' day'. ($lastRegDate == 1 ? '' : 's'), 'lastRegDate' => ($_INDEX_LAST_REGDATE = date_diff(date_create(date('Y-m-d', $_INDEX_NEWEST_USER['regdate'])), date_create(date('Y-m-d')))->format('%a')) .' day'. ($_INDEX_LAST_REGDATE == 1 ? '' : 's'),
'chatOnline' => ($chatOnline = count(SockChat::getOnlineUsers())) .' user'. ($chatOnline == 1 ? '' : 's'), 'chatOnline' => ($_INDEX_CHAT_ONLINE = count(SockChat::getOnlineUsers())) .' user'. ($_INDEX_CHAT_ONLINE == 1 ? '' : 's'),
'onlineUsers' => Users::checkAllOnline() 'onlineUsers' => Users::checkAllOnline()
]; ];

View file

@ -40,8 +40,8 @@ if(isset($_GET['u'])) {
$renderData['page'] = [ $renderData['page'] = [
'title' => ($_PROFILE_USER_DATA['id'] < 1 || $_PROFILE_USER_DATA['password_algo'] == 'nologin' ? 'User not found!' : 'Profile of '. $_PROFILE_USER_DATA['username']), 'title' => ($_PROFILE_USER_DATA['id'] < 1 || $_PROFILE_USER_DATA['password_algo'] == 'nologin' ? 'User not found!' : 'Profile of '. $_PROFILE_USER_DATA['username']),
'style' => ($_PROFILE_USER_DATA['background_url'] ? [ 'style' => ($_PROFILE_USER_DATA['background_url'] ? [
'.userBackground' => [ '#userBackground' => [
'background' => 'url("/bg/'. $_PROFILE_USER_DATA['id'] .'") no-repeat fixed center center / cover transparent !important', 'background' => 'url("/bg/'. $_PROFILE_USER_DATA['id'] .'") no-repeat center center / cover transparent !important',
'position' => 'fixed', 'position' => 'fixed',
'top' => '0', 'top' => '0',
'bottom' => '0', 'bottom' => '0',