notifications + edgy purple
This commit is contained in:
parent
34cf8a1803
commit
28b02e567c
10 changed files with 517 additions and 101 deletions
|
@ -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
|
||||||
|
|
|
@ -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."
|
||||||
|
}
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
|
@ -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
|
||||||
|
@ -70,7 +96,18 @@
|
||||||
|
|
||||||
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 }}" />
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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');
|
|
||||||
|
|
||||||
if(sound) {
|
// Grab the container and create an ID
|
||||||
var sound = document.getElementById('notifsnd');
|
var container = document.getElementById('notifications');
|
||||||
|
var identifier = 'sakura-notification-' + Date.now();
|
||||||
|
|
||||||
sound.volume = 1.0;
|
// Create the notification element and children
|
||||||
sound.currentTime = 0;
|
var notif = document.createElement('div');
|
||||||
sound.play();
|
var notifIcon = document.createElement('div');
|
||||||
}
|
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');
|
||||||
|
|
||||||
window.setTimeout(function() {
|
// Add ID and class on notification container
|
||||||
$('#notif'+id).fadeOut('slow',function() {
|
notif.className = 'notification-enter';
|
||||||
$('#notif'+id).remove();
|
notif.setAttribute('id', identifier);
|
||||||
});
|
|
||||||
}, 2500);
|
|
||||||
|
|
||||||
return true;
|
// Add icon
|
||||||
}
|
notifIcon .className = 'notification-icon';
|
||||||
|
if(content.img.substring(0, 5) == "FONT:") {
|
||||||
|
|
||||||
function notificationRequest() {
|
var iconCont = document.createElement('div');
|
||||||
var notificationURL = 'http://sys.flashii.net/udata?notifications';
|
iconCont.className = 'font-icon fa ' + content.img.replace('FONT:', '') + ' fa-4x';
|
||||||
|
|
||||||
if(window.XMLHttpRequest) {
|
|
||||||
request = new XMLHttpRequest();
|
|
||||||
} else if(window.ActiveXObject) {
|
|
||||||
try {
|
|
||||||
request = new ActiveXObject("Msxml2.XMLHTTP");
|
|
||||||
}
|
|
||||||
catch(e) {
|
|
||||||
try {
|
|
||||||
request = new ActiveXObject("Microsoft.XMLHTTP");
|
|
||||||
}
|
|
||||||
catch(e) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!request) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
request.onreadystatechange = function() {
|
|
||||||
if(request.readyState === 4) {
|
|
||||||
if(request.status === 200) {
|
|
||||||
var notifGet = JSON.parse(request.responseText);
|
|
||||||
|
|
||||||
notifGet[0].notifications.forEach(function(data) {
|
|
||||||
if(data.time >= epochTime()+7 && !$('#notif'+epochTime()).length) {
|
|
||||||
notification(data.id, data.content, true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
//if(epochTime() <= epochTime()+1 && !$('#notif'+epochTime()).length) {
|
|
||||||
// notification(epochTime(), notifGet[0].notifications[0].notif1, true);
|
|
||||||
//}
|
|
||||||
} else {
|
} else {
|
||||||
notification('ERROR'+epochTime(), 'Error: Was not able to get notification data.',false);
|
|
||||||
|
var iconCont = document.createElement('img');
|
||||||
|
iconCont.setAttribute('alt', identifier);
|
||||||
|
iconCont.setAttribute('src', content.img);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
notifIcon .appendChild(iconCont);
|
||||||
|
notif .appendChild(notifIcon);
|
||||||
|
|
||||||
|
// Add content
|
||||||
|
var notifTitleNode = document.createTextNode(content.title);
|
||||||
|
var notifTextNode = document.createTextNode(content.text);
|
||||||
|
notifContent .className = 'notification-content';
|
||||||
|
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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Closing a notification box
|
||||||
|
function notifyClose(id) {
|
||||||
|
|
||||||
|
// Get the element and assign it to a variable
|
||||||
|
var element = document.getElementById(id);
|
||||||
|
|
||||||
|
// Do the animation
|
||||||
|
element.className = 'notification-exit';
|
||||||
|
|
||||||
|
// Remove the element after 500 milliseconds (animation takes 400)
|
||||||
|
setTimeout(function() {
|
||||||
|
|
||||||
|
// Use the later defined removeId function
|
||||||
|
removeId(id);
|
||||||
|
|
||||||
|
}, 410);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Opening a link to a notifcated thing (what even)
|
||||||
|
function notifyOpen(id) {
|
||||||
|
|
||||||
|
var sakuraHref = document.getElementById(id).getAttribute('sakurahref');
|
||||||
|
|
||||||
|
if(typeof sakuraHref !== 'undefined')
|
||||||
|
window.location = sakuraHref;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request notifications
|
||||||
|
function notifyRequest(session) {
|
||||||
|
|
||||||
|
// Create XMLHttpRequest and notifyURL
|
||||||
|
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 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.');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make the request
|
||||||
|
notificationWatcher.open('GET', notifyURL, true);
|
||||||
|
notificationWatcher.send();
|
||||||
|
|
||||||
}
|
}
|
||||||
request.open('GET', notificationURL);
|
|
||||||
request.send();
|
|
||||||
setTimeout(notificationRequest, 5000);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// Donate page specific features
|
// Donate page specific features
|
||||||
function donatePage(id) {
|
function donatePage(id) {
|
||||||
|
|
BIN
content/images/emoticons/sad.png
Normal file
BIN
content/images/emoticons/sad.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 502 B |
|
@ -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);
|
||||||
|
|
Reference in a new issue