notifications + edgy purple

This commit is contained in:
flash 2015-05-09 00:56:55 +00:00
parent 34cf8a1803
commit 28b02e567c
10 changed files with 517 additions and 101 deletions

View file

@ -15,7 +15,7 @@ CREATE TABLE `fii_actioncodes` (
`actkey` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'The URL key for using this code.', `actkey` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'The URL key for using this code.',
`instruction` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Things the backend should do upon using this code', `instruction` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Things the backend should do upon using this code',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `fii_apikeys`; DROP TABLE IF EXISTS `fii_apikeys`;
@ -53,14 +53,14 @@ INSERT INTO `fii_config` (`config_name`, `config_value`) VALUES
('recaptcha_public', ''), ('recaptcha_public', ''),
('recaptcha_private', ''), ('recaptcha_private', ''),
('charset', 'utf-8'), ('charset', 'utf-8'),
('cookie_prefix', 'fii_'), ('cookie_prefix', 'sakura_'),
('cookie_domain', 'iihsalf.net'), ('cookie_domain', 'yourdomain.com'),
('cookie_path', '/'), ('cookie_path', '/'),
('site_style', 'yuuno'), ('site_style', 'yuuno'),
('manage_style', 'broomcloset'), ('manage_style', 'broomcloset'),
('allow_registration', '0'), ('allow_registration', '0'),
('smtp_server', ''), ('smtp_server', ''),
('smtp_auth', ''), ('smtp_auth', '1'),
('smtp_secure', ''), ('smtp_secure', ''),
('smtp_port', ''), ('smtp_port', ''),
('smtp_username', ''), ('smtp_username', ''),
@ -69,7 +69,7 @@ INSERT INTO `fii_config` (`config_name`, `config_value`) VALUES
('smtp_replyto_name', ''), ('smtp_replyto_name', ''),
('smtp_from_email', ''), ('smtp_from_email', ''),
('smtp_from_name', ''), ('smtp_from_name', ''),
('sitename', 'Development Palace'), ('sitename', 'Sakura'),
('recaptcha', '1'), ('recaptcha', '1'),
('require_activation', '1'), ('require_activation', '1'),
('require_registration_code', '0'), ('require_registration_code', '0'),
@ -101,8 +101,9 @@ CREATE TABLE `fii_forums` (
`forum_topics` bigint(255) unsigned NOT NULL DEFAULT '0' COMMENT 'Topic count of the forum.', `forum_topics` bigint(255) unsigned NOT NULL DEFAULT '0' COMMENT 'Topic count of the forum.',
`forum_last_post_id` bigint(255) unsigned NOT NULL DEFAULT '0' COMMENT 'ID of last post in forum.', `forum_last_post_id` bigint(255) unsigned NOT NULL DEFAULT '0' COMMENT 'ID of last post in forum.',
`forum_last_poster_id` bigint(255) unsigned NOT NULL DEFAULT '0' COMMENT 'ID of last poster in forum.', `forum_last_poster_id` bigint(255) unsigned NOT NULL DEFAULT '0' COMMENT 'ID of last poster in forum.',
`forum_icon` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Display icon for the forum.',
PRIMARY KEY (`forum_id`) PRIMARY KEY (`forum_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `fii_infopages`; DROP TABLE IF EXISTS `fii_infopages`;
@ -138,6 +139,21 @@ CREATE TABLE `fii_news` (
) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; ) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `fii_notifications`;
CREATE TABLE `fii_notifications` (
`id` bigint(255) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Automatically generated ID by MySQL for management.',
`uid` bigint(255) unsigned NOT NULL DEFAULT '0' COMMENT 'User ID this notification is intended for.',
`timestamp` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'Timestamp when this notification was created.',
`notif_read` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'Toggle for unread and read.',
`notif_title` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Title displayed on the notification.',
`notif_text` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Text displayed.',
`notif_link` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT 'Link (empty for no link).',
`notif_img` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Image path, prefix with font: to use a font class instead of an image.',
`notif_timeout` int(16) unsigned NOT NULL DEFAULT '0' COMMENT 'How long the notification should stay on screen in milliseconds, 0 for forever.',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `fii_posts`; DROP TABLE IF EXISTS `fii_posts`;
CREATE TABLE `fii_posts` ( CREATE TABLE `fii_posts` (
`post_id` bigint(255) unsigned NOT NULL AUTO_INCREMENT COMMENT 'MySQL Generated ID used for sorting.', `post_id` bigint(255) unsigned NOT NULL AUTO_INCREMENT COMMENT 'MySQL Generated ID used for sorting.',
@ -195,17 +211,6 @@ CREATE TABLE `fii_ranks` (
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
TRUNCATE `fii_ranks`;
INSERT INTO `fii_ranks` (`id`, `name`, `multi`, `colour`, `description`, `title`, `is_premium`) VALUES
(1, 'Deactivated', 0, '#555', 'Users that are yet to be activated or that deactivated their own account.', 'Deactivated', 0),
(2, 'Regular user', 1, 'inherit', 'Regular users with regular permissions.', 'Regular user', 0),
(3, 'Site moderator', 1, '#0A0', 'Users with special permissions like being able to ban and modify users if needed.', 'Staff', 1),
(4, 'Administrator', 1, '#C00', 'Users that manage the server and everything around that.', 'Administrator', 1),
(5, 'Developer', 1, '#824CA0', 'Users that either create or test new features of the site.', 'Staff', 1),
(6, 'Bot', 1, '#9E8DA7', 'Reserved user accounts for services.', 'Bot', 0),
(7, 'Chat moderator', 1, '#09F', 'Moderators of the chat room.', 'Staff', 1),
(8, 'Tenshi', 0, '#EE9400', 'Users that donated $5.00 or more in order to keep the site and it\'s services alive!', 'Tenshi', 1),
(9, 'Alumnii', 0, '#FF69B4', 'People who have contributed to the community but have moved on or resigned.', 'Alumnii', 1);
DROP TABLE IF EXISTS `fii_regcodes`; DROP TABLE IF EXISTS `fii_regcodes`;
CREATE TABLE `fii_regcodes` ( CREATE TABLE `fii_regcodes` (
@ -229,7 +234,7 @@ CREATE TABLE `fii_sessions` (
`expire` int(64) unsigned NOT NULL COMMENT 'The timestamp for when this session should end, -1 for permanent. ', `expire` int(64) unsigned NOT NULL COMMENT 'The timestamp for when this session should end, -1 for permanent. ',
`remember` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'If set to 1 session will be extended each time a page is loaded.', `remember` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'If set to 1 session will be extended each time a page is loaded.',
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=62 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; ) ENGINE=InnoDB AUTO_INCREMENT=65 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `fii_sock_perms`; DROP TABLE IF EXISTS `fii_sock_perms`;
@ -296,8 +301,8 @@ CREATE TABLE `fii_users` (
`password_chan` int(16) unsigned NOT NULL COMMENT 'Last time the user changed their password.', `password_chan` int(16) unsigned NOT NULL COMMENT 'Last time the user changed their password.',
`password_new` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT 'Field with array containing new password data beit that they requested a password change.', `password_new` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT 'Field with array containing new password data beit that they requested a password change.',
`email` varchar(32) COLLATE utf8_bin NOT NULL COMMENT 'E-mail of the user for password restoring etc.', `email` varchar(32) COLLATE utf8_bin NOT NULL COMMENT 'E-mail of the user for password restoring etc.',
`rank_main` mediumint(4) unsigned NOT NULL COMMENT 'Main rank of the user.', `rank_main` mediumint(4) unsigned NOT NULL DEFAULT '0' COMMENT 'Main rank of the user.',
`ranks` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'Array containing the ranks the user is part of.', `ranks` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '[0]' COMMENT 'Array containing the ranks the user is part of.',
`name_colour` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT 'Additional name colour, when empty colour defaults to group colour.', `name_colour` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT 'Additional name colour, when empty colour defaults to group colour.',
`register_ip` varchar(16) COLLATE utf8_bin NOT NULL COMMENT 'IP used for the creation of this account.', `register_ip` varchar(16) COLLATE utf8_bin NOT NULL COMMENT 'IP used for the creation of this account.',
`last_ip` varchar(16) COLLATE utf8_bin NOT NULL COMMENT 'Last IP that was used to log into this account.', `last_ip` varchar(16) COLLATE utf8_bin NOT NULL COMMENT 'Last IP that was used to log into this account.',
@ -305,15 +310,16 @@ CREATE TABLE `fii_users` (
`profile_md` text COLLATE utf8_bin COMMENT 'Markdown customise page thing on the profile of the user.', `profile_md` text COLLATE utf8_bin COMMENT 'Markdown customise page thing on the profile of the user.',
`avatar_url` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT 'Full url to the user''s avatar.', `avatar_url` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT 'Full url to the user''s avatar.',
`background_url` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT 'Full url to the user''s profile background.', `background_url` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT 'Full url to the user''s profile background.',
`regdate` int(16) unsigned NOT NULL COMMENT 'Timestamp of account creation.', `regdate` int(16) unsigned NOT NULL DEFAULT '0' COMMENT 'Timestamp of account creation.',
`lastdate` int(16) unsigned NOT NULL COMMENT 'Last time anything was done on this account.', `lastdate` int(16) unsigned NOT NULL DEFAULT '0' COMMENT 'Last time anything was done on this account.',
`lastunamechange` int(16) unsigned NOT NULL COMMENT 'Last username change.', `lastunamechange` int(16) unsigned NOT NULL DEFAULT '0' COMMENT 'Last username change.',
`birthday` varchar(16) COLLATE utf8_bin DEFAULT NULL COMMENT 'Birthdate of the user.', `birthday` varchar(16) COLLATE utf8_bin DEFAULT NULL COMMENT 'Birthdate of the user.',
`posts` int(16) unsigned NOT NULL DEFAULT '0' COMMENT 'Amount of posts the user has made on the forum.',
`country` varchar(4) COLLATE utf8_bin NOT NULL COMMENT 'Contains ISO 3166 country code of user''s registration location.', `country` varchar(4) COLLATE utf8_bin NOT NULL COMMENT 'Contains ISO 3166 country code of user''s registration location.',
`profile_data` text COLLATE utf8_bin NOT NULL COMMENT 'Modular array containing profile data.', `profile_data` text COLLATE utf8_bin NOT NULL COMMENT 'Modular array containing profile data.',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE KEY `username_clean` (`username_clean`) UNIQUE KEY `username_clean` (`username_clean`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `fii_warnings`; DROP TABLE IF EXISTS `fii_warnings`;
@ -328,4 +334,4 @@ CREATE TABLE `fii_warnings` (
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
-- 2015-05-05 06:18:36 -- 2015-05-08 17:47:36

View file

@ -2,6 +2,19 @@
"versions": { "versions": {
"Eminence": {
"colour": "#6C3082",
"builds": [
"20150508",
"20150509"
]
},
"Heliotrope": { "Heliotrope": {
"colour": "#DF73FF", "colour": "#DF73FF",
@ -964,6 +977,32 @@
"change": "Moved panel on the right site of the index to its own template file." "change": "Moved panel on the right site of the index to its own template file."
} }
],
"20150508": [
{
"type": "ADD",
"change": "Added notification system."
}
],
"20150509": [
{
"type": "FIX",
"change": "Fixed missing newline in a template file."
},
{
"type": "ADD",
"change": "Added function to actually create notifications."
},
{
"type": "FIX",
"change": "Fixed avatar border being depositioned."
}
] ]
} }

View file

@ -932,4 +932,76 @@ class Users {
} }
// Get a user's notifications
public static function getNotifications($uid = null, $timediff = 0, $excludeRead = true, $markRead = false) {
// Prepare conditions
$conditions = array();
$conditions['uid'] = [($uid ? $uid : Session::$userId), '='];
if($timediff)
$conditions['timestamp'] = [time() - $timediff, '>'];
if($excludeRead)
$conditions['notif_read'] = [0, '='];
// Get notifications for the database
$notifications = Database::fetch('notifications', true, $conditions);
// Mark the notifications as read
if($markRead) {
// Iterate over all entries
foreach($notifications as $notification) {
// If the notifcation is already read skip
if($notification['notif_read'])
continue;
// Mark them as read
self::markNotificationRead($notification['id']);
}
}
// Return the notifications
return $notifications;
}
// Marking notifications as read
public static function markNotificationRead($id, $mode = true) {
// Execute an update statement
Database::update('notifications', [
[
'notif_read' => ($mode ? 1 : 0)
],
[
'id' => [$id, '=']
]
]);
}
// Adding a new notification
public static function createNotification($user, $title, $text, $timeout = 60000, $img = 'FONT:fa-info-circle', $link = '', $sound = 0) {
// Get current timestamp
$time = time();
// Insert it into the database
Database::insert('notifications', [
'uid' => Session::$userId,
'timestamp' => $time,
'notif_read' => 0,
'notif_sound' => ($sound ? 1 : 0),
'notif_title' => $title,
'notif_text' => $text,
'notif_link' => $link,
'notif_img' => $img,
'notif_timeout' => $timeout
]);
}
} }

View file

@ -8,10 +8,10 @@
namespace Sakura; namespace Sakura;
// Define Sakura version // Define Sakura version
define('SAKURA_VERSION', '20150506'); define('SAKURA_VERSION', '20150508');
define('SAKURA_VLABEL', 'Heliotrope'); define('SAKURA_VLABEL', 'Eminence');
define('SAKURA_VTYPE', 'Development'); define('SAKURA_VTYPE', 'Development');
define('SAKURA_COLOUR', '#DF73FF'); define('SAKURA_COLOUR', '#6C3082');
// Define Sakura Path // Define Sakura Path
define('ROOT', str_replace(basename(__DIR__), '', dirname(__FILE__))); define('ROOT', str_replace(basename(__DIR__), '', dirname(__FILE__)));
@ -72,7 +72,10 @@ $renderData = array(
'lockauth' => Configuration::getConfig('lock_authentication'), 'lockauth' => Configuration::getConfig('lock_authentication'),
'requireregcodes' => Configuration::getConfig('require_registration_code'), 'requireregcodes' => Configuration::getConfig('require_registration_code'),
'requireactiveate' => Configuration::getConfig('require_activation'), 'requireactiveate' => Configuration::getConfig('require_activation'),
'sitename' => Configuration::getConfig('sitename') 'sitename' => Configuration::getConfig('sitename'),
'cookieprefix' => Configuration::getConfig('cookie_prefix'),
'cookiedomain' => Configuration::getConfig('cookie_domain'),
'cookiepath' => Configuration::getConfig('cookie_path')
], ],
'php' => [ 'php' => [
'sessionid' => \session_id(), 'sessionid' => \session_id(),

View file

@ -31,4 +31,4 @@ there's <b>{{ stats.chatOnline }}</b> in chat right now and the forum has <b>{{
{% endfor %} {% endfor %}
{% else %} {% else %}
There were no online users in the past 5 minutes. There were no online users in the past 5 minutes.
{% endif %} {% endif %}

View file

@ -28,6 +28,32 @@
<!-- JS --> <!-- JS -->
<script type="text/javascript" src="{{ sakura.resources }}/js/yuuno.js"></script> <script type="text/javascript" src="{{ sakura.resources }}/js/yuuno.js"></script>
<script type="text/javascript"> <script type="text/javascript">
// Create an object so we can access certain settings from remote JavaScript files
var sakuraVars = {
"cookie": {
"prefix": "{{ sakura.cookieprefix }}",
"domain": "{{ sakura.cookiedomain }}",
"path": "{{ sakura.cookiepath }}"
},
"resources": "{{ sakura.resources }}",
"urls": {
{% for name,url in sakura.urls %}
"{{ name }}": "{{ url }}"{% if loop.index != sakura.urls|length %}, {% endif %}
{% endfor %}
},
"checklogin": {% if user.checklogin %}true{% else %}false{% endif %}
};
{% if not user.checklogin and not sakura.lockauth %} {% if not user.checklogin and not sakura.lockauth %}
// Setting the shit so clicking the login link doesn't redirect to /login // Setting the shit so clicking the login link doesn't redirect to /login
@ -67,10 +93,21 @@
headerLogoutLink.setAttribute('onclick', 'doHeaderLogout();'); headerLogoutLink.setAttribute('onclick', 'doHeaderLogout();');
} }
function doHeaderLogout() { function doHeaderLogout() {
generateForm("headerLogoutForm", {"class":"hidden","method":"post","action":"//{{ sakura.urls.main }}/logout"},{"mode":"logout","ajax":"true","time":"{{ php.time }}","session":"{{ php.sessionid }}","redirect":"{{ sakura.currentpage }}"},"contentwrapper"); generateForm("headerLogoutForm", {
"class": "hidden",
"method": "post",
"action": "//{{ sakura.urls.main }}/logout"
},
{
"mode": "logout",
"ajax": "true",
"time": "{{ php.time }}",
"session": "{{ php.sessionid }}",
"redirect": "{{ sakura.currentpage }}"
}, "contentwrapper");
setTimeout(function(){ setTimeout(function(){
submitPost("headerLogoutForm", true, "Logging out...") submitPost("headerLogoutForm", true, "Logging out...")
@ -85,6 +122,12 @@
// Login form under header and ajax logout // Login form under header and ajax logout
initHeaderLoginForm(); initHeaderLoginForm();
{% if user.checklogin %}
// Make notification requests (there's a seperate one to make it happen before the first 60 seconds)
notifyRequest('{{ php.sessionid }}');
setInterval(function(){notifyRequest('{{ php.sessionid }}');}, 60000);
{% endif %}
{% if php.self == '/authenticate.php' and not sakura.lockauth %} {% if php.self == '/authenticate.php' and not sakura.lockauth %}
// AJAX Form Submission // AJAX Form Submission
var forms = { var forms = {
@ -158,6 +201,7 @@
</div> </div>
</div> </div>
<div id="contentwrapper"> <div id="contentwrapper">
<div id="notifications"></div>
{% if not user.checklogin %} {% if not user.checklogin %}
<form method="post" action="/authenticate" class="hidden" id="headerLoginForm" onkeydown="formEnterCatch(event, 'headerLoginButton');"> <form method="post" action="/authenticate" class="hidden" id="headerLoginForm" onkeydown="formEnterCatch(event, 'headerLoginButton');">
<input type="hidden" name="redirect" value="{{ sakura.currentpage }}" /> <input type="hidden" name="redirect" value="{{ sakura.currentpage }}" />

View file

@ -172,24 +172,106 @@ a.gotop:active {
display: block; display: block;
} }
} }
@keyframes slideInFromRight { /* Requires position: relative to be set on the element */
0% {
right: -100%;
}
100% {
right: 0%;
}
}
@keyframes slideOutToBottom { /* Read comment above */
0% {
bottom: 0%;
}
100% {
bottom: -100%;
}
}
/* Notifications */ /* Notifications */
.notifications { #notifications {
position: fixed; position: fixed;
top: 5px; bottom: 5px;
right: 5px; right: 5px;
z-index: 3; z-index: 3;
font-family: "Segoe UI", sans-serif;
overflow-y: auto;
overflow-x: hidden;
max-height: 510px;
max-width: 600px;
text-align: right;
} }
.notifications div { #notifications > div {
min-width: 200px; cursor: pointer;
max-width: 400px; text-align: left;
background: rgba(0, 0, 0, .6); display: inline-block;
border: 2px solid #306; height: 80px;
border-radius: 10px; background: rgba(113, 74, 150, .9);
padding: 10px; border: 1px solid #507;
border-right-width: 5px;
color: #FFF; color: #FFF;
font-weight: 700; padding: 2px 0 2px 2px;
margin: 5px; margin: 5px;
position: relative;
box-shadow: 0 0 4px rgba(0, 0, 0, .9);
}
#notifications > .notification-enter {
animation: slideInFromRight 1 .4s, fadeIn 1 .4s;
}
#notifications > .notification-exit {
animation: slideOutToBottom 1 .4s, fadeOut 1 .4s;
}
#notifications > div > .notification-icon {
float: left;
width: 80px;
height: 80px;
text-align: center;
background: rgba(0, 0, 0, .5);
display: block;
}
#notifications > div > .notification-icon > img {
max-height: 80px;
max-width: 80px;
}
#notifications > div > .notification-icon > .font-icon {
margin: .34em 0;
}
#notifications > div > .notification-content {
float: left;
min-width: 350px;
max-width: 450px;
padding-right: 6px;
border-left: 1px solid rgb(85, 0, 119);
height: 80px;
margin-left: 2px;
padding-left: 8px;
}
#notifications > div > .notification-content > .notification-title {
font-weight: 300;
font-size: 1.7em;
margin-top: 1em;
}
#notifications > div > .notification-close:before {
font-family: FontAwesome;
content: "\f00d";
}
#notifications > div > .notification-close {
font-size: 2em;
float: right;
height: 80px;
width: 20px;
background: #507;
margin-top: -3px;
padding-bottom: 6px;
padding-left: 2px;
border-left: 3px solid #507;
line-height: 3.4em;
text-align: center;
display: none;
}
#notifications > div:hover > .notification-close {
display: block;
} }
/* Site Header Styling */ /* Site Header Styling */

View file

@ -76,72 +76,208 @@ function epochTime() {
} }
/* // Create a notification box
"Delayed" for now (not really any use for it atm) function notifyUI(content) {
function notification(id, content, sound) {
$('.notifications').hide().append('<div id="notif'+id+'">'+content+'</div>').fadeIn('slow'); // Grab the container and create an ID
var container = document.getElementById('notifications');
if(sound) { var identifier = 'sakura-notification-' + Date.now();
var sound = document.getElementById('notifsnd');
// Create the notification element and children
sound.volume = 1.0; var notif = document.createElement('div');
sound.currentTime = 0; var notifIcon = document.createElement('div');
sound.play(); var notifContent = document.createElement('div');
var notifTitle = document.createElement('div');
var notifText = document.createElement('div');
var notifClose = document.createElement('div');
var notifClear = document.createElement('div');
// Add ID and class on notification container
notif.className = 'notification-enter';
notif.setAttribute('id', identifier);
// Add icon
notifIcon .className = 'notification-icon';
if(content.img.substring(0, 5) == "FONT:") {
var iconCont = document.createElement('div');
iconCont.className = 'font-icon fa ' + content.img.replace('FONT:', '') + ' fa-4x';
} else {
var iconCont = document.createElement('img');
iconCont.setAttribute('alt', identifier);
iconCont.setAttribute('src', content.img);
} }
notifIcon .appendChild(iconCont);
window.setTimeout(function() { notif .appendChild(notifIcon);
$('#notif'+id).fadeOut('slow',function() {
$('#notif'+id).remove(); // Add content
}); var notifTitleNode = document.createTextNode(content.title);
}, 2500); var notifTextNode = document.createTextNode(content.text);
notifContent .className = 'notification-content';
return true; notifTitle .className = 'notification-title';
notifText .className = 'notification-text';
notifTitle .appendChild(notifTitleNode);
notifText .appendChild(notifTextNode);
if(content.link) {
notif .setAttribute('sakurahref', content.link);
notifContent.setAttribute('onclick', 'notifyOpen(this.parentNode.id);');
}
notifContent .appendChild(notifTitle);
notifContent .appendChild(notifText);
notif .appendChild(notifContent);
// Add close button
notifClose .className = 'notification-close';
notifClose .setAttribute('onclick', 'notifyClose(this.parentNode.id);');
notif .appendChild(notifClose);
// Add .clear
notifClear .className = 'clear';
notif .appendChild(notifClear);
// Append the notification to the document so it actually shows up to the user also add the link
container.appendChild(notif);
// Play sound if requested
if(content.sound > 0) {
// Create sound element and mp3 and ogg sources
var sound = document.createElement('audio');
var soundMP3 = document.createElement('source');
var soundOGG = document.createElement('source');
// Assign the proper attributes to the sources
soundMP3.setAttribute('src', '//' + sakuraVars.urls.content + '/sounds/notify.mp3');
soundMP3.setAttribute('type', 'audio/mp3');
soundOGG.setAttribute('src', '//' + sakuraVars.urls.content + '/sounds/notify.ogg');
soundOGG.setAttribute('type', 'audio/ogg');
// Append the children
sound.appendChild(soundMP3);
sound.appendChild(soundOGG);
// Play the sound
sound.play();
}
// If keepalive is 0 keep the notification open "forever" (until the user closes it or changes the page)
if(content.timeout > 0) {
// Set set a timeout and execute notifyClose() after amount of milliseconds specified
setTimeout(function() {
// Use the later defined notifyClose function
notifyClose(identifier);
}, content.timeout);
}
} }
function notificationRequest() { // Closing a notification box
var notificationURL = 'http://sys.flashii.net/udata?notifications'; function notifyClose(id) {
if(window.XMLHttpRequest) { // Get the element and assign it to a variable
request = new XMLHttpRequest(); var element = document.getElementById(id);
} else if(window.ActiveXObject) {
try { // Do the animation
request = new ActiveXObject("Msxml2.XMLHTTP"); element.className = 'notification-exit';
}
catch(e) { // Remove the element after 500 milliseconds (animation takes 400)
try { setTimeout(function() {
request = new ActiveXObject("Microsoft.XMLHTTP");
} // Use the later defined removeId function
catch(e) {} removeId(id);
}
} }, 410);
if(!request) { }
return false;
} // Opening a link to a notifcated thing (what even)
function notifyOpen(id) {
request.onreadystatechange = function() {
if(request.readyState === 4) { var sakuraHref = document.getElementById(id).getAttribute('sakurahref');
if(request.status === 200) {
var notifGet = JSON.parse(request.responseText); if(typeof sakuraHref !== 'undefined')
window.location = sakuraHref;
notifGet[0].notifications.forEach(function(data) {
if(data.time >= epochTime()+7 && !$('#notif'+epochTime()).length) { }
notification(data.id, data.content, true);
} // Request notifications
}); function notifyRequest(session) {
//if(epochTime() <= epochTime()+1 && !$('#notif'+epochTime()).length) { // Create XMLHttpRequest and notifyURL
// notification(epochTime(), notifGet[0].notifications[0].notif1, true); var notificationWatcher = new XMLHttpRequest();
//} var notifyURL = '//' + sakuraVars.urls.main + '/settings.php?request-notifications=true&time=' + epochTime() + '&session=' + session;
// Wait for the ready state to change
notificationWatcher.onreadystatechange = function() {
// Wait for it to reach the "complete" stage
if(notificationWatcher.readyState === 4) {
// Continue if the HTTP return was 200
if(notificationWatcher.status === 200) {
// Assign the JSON parsed content to a variable
var notifyGet = JSON.parse(notificationWatcher.responseText);
// If nothing was set stop
if(typeof notifyGet == 'undefined') {
// Tell the user something went wrong...
notifyUI({
"title": "An error occurred!",
"text": "If this problem persists please report this to the administrator.",
"img": "FONT:fa-exclamation-triangle",
"timeout": 60000,
"sound": false
});
// ...and log an error message to to console..
console.log('[SAKURA NOTIFICATION DEBUG] Invalid return type.');
// ...then prevent the function from contiuing
return;
}
// Go over every return notification and pass the object to it
for(var notifyID in notifyGet)
notifyUI(notifyGet[notifyID]);
} else { } else {
notification('ERROR'+epochTime(), 'Error: Was not able to get notification data.',false);
// ELse tell the user there was an internal server error...
notifyUI({
"title": "An internal server error occurred!",
"text": "If this problem persists please report this to the administrator.",
"img": "FONT:fa-chain-broken",
"timeout": 60000,
"sound": false
});
// ...and log a thing to the JavaScript console
console.log('[SAKURA NOTIFICATION DEBUG] HTTP return wasn\'t 200.');
} }
} }
} }
request.open('GET', notificationURL);
request.send(); // Make the request
setTimeout(notificationRequest, 5000); notificationWatcher.open('GET', notifyURL, true);
}*/ notificationWatcher.send();
}
// Donate page specific features // Donate page specific features
function donatePage(id) { function donatePage(id) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 502 B

View file

@ -9,5 +9,39 @@ namespace Sakura;
// Include components // Include components
require_once str_replace(basename(__DIR__), '', dirname(__FILE__)) .'_sakura/sakura.php'; require_once str_replace(basename(__DIR__), '', dirname(__FILE__)) .'_sakura/sakura.php';
// Notifications
if(isset($_REQUEST['request-notifications']) && $_REQUEST['request-notifications']) {
// Create the notification container array
$notifications = array();
// Check if the user is logged in
if(Users::checkLogin() && isset($_REQUEST['time']) && $_REQUEST['time'] > (time() - 1000) && isset($_REQUEST['session']) && $_REQUEST['session'] == session_id()) {
// Get the user's notifications from the past forever but exclude read notifications
$userNotifs = Users::getNotifications(null, 0, true, true);
// Add the proper values to the array
foreach($userNotifs as $notif) {
$notifications[$notif['timestamp']] = array();
$notifications[$notif['timestamp']]['read'] = $notif['notif_read'];
$notifications[$notif['timestamp']]['title'] = $notif['notif_title'];
$notifications[$notif['timestamp']]['text'] = $notif['notif_text'];
$notifications[$notif['timestamp']]['link'] = $notif['notif_link'];
$notifications[$notif['timestamp']]['img'] = $notif['notif_img'];
$notifications[$notif['timestamp']]['timeout'] = $notif['notif_timeout'];
$notifications[$notif['timestamp']]['sound'] = $notif['notif_sound'];
}
}
// Set header, convert the array to json, print it and exit
print json_encode($notifications);
exit;
}
// Print page contents // Print page contents
print Templates::render('ucp/index.tpl', $renderData); print Templates::render('ucp/index.tpl', $renderData);