FUCK
This commit is contained in:
parent
0dc204fcb3
commit
3d8c30e8b6
32 changed files with 178 additions and 89 deletions
|
@ -34,7 +34,7 @@ class Controller
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function json($object, $operators = JSON_FORCE_OBJECT | JSON_NUMERIC_CHECK | JSON_BIGINT_AS_STRING)
|
public function json($object, $operators = null)
|
||||||
{
|
{
|
||||||
header('Content-Type: application/json; charset=utf-8');
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
return json_encode($object, $operators);
|
return json_encode($object, $operators);
|
||||||
|
|
|
@ -36,15 +36,15 @@ class Notification
|
||||||
if ($data) {
|
if ($data) {
|
||||||
$data = $data[0];
|
$data = $data[0];
|
||||||
|
|
||||||
$this->id = $data->alert_id;
|
$this->id = intval($data->alert_id);
|
||||||
$this->user = $data->user_id;
|
$this->user = intval($data->user_id);
|
||||||
$this->time = $data->alert_timestamp;
|
$this->time = intval($data->alert_timestamp);
|
||||||
$this->read = intval($data->alert_read) !== 0;
|
$this->read = intval($data->alert_read) !== 0;
|
||||||
$this->title = $data->alert_title;
|
$this->title = $data->alert_title;
|
||||||
$this->text = $data->alert_text;
|
$this->text = $data->alert_text;
|
||||||
$this->link = $data->alert_link;
|
$this->link = $data->alert_link;
|
||||||
$this->image = $data->alert_img;
|
$this->image = $data->alert_img;
|
||||||
$this->timeout = $data->alert_timeout;
|
$this->timeout = intval($data->alert_timeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
app/User.php
10
app/User.php
|
@ -214,13 +214,6 @@ class User
|
||||||
*/
|
*/
|
||||||
public $youtube = '';
|
public $youtube = '';
|
||||||
|
|
||||||
/**
|
|
||||||
* The thing that indicates if it's an id or a name.
|
|
||||||
*
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
public $youtubeType = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The user's steam community username.
|
* The user's steam community username.
|
||||||
*
|
*
|
||||||
|
@ -369,7 +362,6 @@ class User
|
||||||
$this->skype = $userRow->user_skype;
|
$this->skype = $userRow->user_skype;
|
||||||
$this->discord = $userRow->user_discord;
|
$this->discord = $userRow->user_discord;
|
||||||
$this->youtube = $userRow->user_youtube;
|
$this->youtube = $userRow->user_youtube;
|
||||||
$this->youtubeType = intval($userRow->user_youtube_type);
|
|
||||||
$this->steam = $userRow->user_steam;
|
$this->steam = $userRow->user_steam;
|
||||||
$this->osu = $userRow->user_osu;
|
$this->osu = $userRow->user_osu;
|
||||||
$this->lastfm = $userRow->user_lastfm;
|
$this->lastfm = $userRow->user_lastfm;
|
||||||
|
@ -1089,7 +1081,7 @@ class User
|
||||||
$alerts = [];
|
$alerts = [];
|
||||||
|
|
||||||
foreach ($alertIds as $alertId) {
|
foreach ($alertIds as $alertId) {
|
||||||
$alerts[$alertId] = new Notification($alertId);
|
$alerts[] = new Notification($alertId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $alerts;
|
return $alerts;
|
||||||
|
|
|
@ -47,9 +47,6 @@ class MoveOptionsAndProfileIntoUsers extends Migration
|
||||||
->nullable()
|
->nullable()
|
||||||
->default(null);
|
->default(null);
|
||||||
|
|
||||||
$table->tinyInteger('user_youtube_type')
|
|
||||||
->default(0);
|
|
||||||
|
|
||||||
$table->string('user_steam', 255)
|
$table->string('user_steam', 255)
|
||||||
->nullable()
|
->nullable()
|
||||||
->default(null);
|
->default(null);
|
||||||
|
@ -82,7 +79,6 @@ class MoveOptionsAndProfileIntoUsers extends Migration
|
||||||
'user_skype',
|
'user_skype',
|
||||||
'user_discord',
|
'user_discord',
|
||||||
'user_youtube',
|
'user_youtube',
|
||||||
'user_youtube_type',
|
|
||||||
'user_steam',
|
'user_steam',
|
||||||
'user_osu',
|
'user_osu',
|
||||||
'user_lastfm',
|
'user_lastfm',
|
||||||
|
|
|
@ -7,9 +7,9 @@ elixir(function(mix) {
|
||||||
mix
|
mix
|
||||||
.less('aitemu/master.less', 'public/css/aitemu.css')
|
.less('aitemu/master.less', 'public/css/aitemu.css')
|
||||||
.less('yuuno/master.less', 'public/css/yuuno.css')
|
.less('yuuno/master.less', 'public/css/yuuno.css')
|
||||||
.typescript('app/**/*.ts', 'public/js/app.js')
|
.typescript('Sakura/**/*.ts', 'public/js/app.js')
|
||||||
.typescript('aitemu/**/*.ts', 'public/js/aitemu.js')
|
.typescript('Aitemu/**/*.ts', 'public/js/aitemu.js')
|
||||||
.typescript('yuuno/**/*.ts', 'public/js/yuuno.js')
|
.typescript('Yuuno/**/*.ts', 'public/js/yuuno.js')
|
||||||
.scripts([
|
.scripts([
|
||||||
nodePath + 'turbolinks/dist/turbolinks.js',
|
nodePath + 'turbolinks/dist/turbolinks.js',
|
||||||
], 'public/js/libraries.js');
|
], 'public/js/libraries.js');
|
||||||
|
|
|
@ -3,6 +3,7 @@ namespace Sakura
|
||||||
export class Config
|
export class Config
|
||||||
{
|
{
|
||||||
public static Revision: number = 0;
|
public static Revision: number = 0;
|
||||||
|
public static UserId: number = 0;
|
||||||
public static SessionId: string = "";
|
public static SessionId: string = "";
|
||||||
public static UserNameMinLength: number = 3;
|
public static UserNameMinLength: number = 3;
|
||||||
public static UserNameMaxLength: number = 16;
|
public static UserNameMaxLength: number = 16;
|
15
resources/assets/typescript/Sakura/INotification.ts
Normal file
15
resources/assets/typescript/Sakura/INotification.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
namespace Sakura
|
||||||
|
{
|
||||||
|
export interface INotification
|
||||||
|
{
|
||||||
|
id: number;
|
||||||
|
user: number;
|
||||||
|
time: number;
|
||||||
|
read: boolean;
|
||||||
|
title: string;
|
||||||
|
text: string;
|
||||||
|
link: string;
|
||||||
|
image: string;
|
||||||
|
timeout: number;
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ namespace Sakura
|
||||||
console.log(this.Supported());
|
console.log(this.Supported());
|
||||||
TimeAgo.Init();
|
TimeAgo.Init();
|
||||||
Friend.Init();
|
Friend.Init();
|
||||||
|
Notifications.Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Supported(): boolean {
|
public static Supported(): boolean {
|
51
resources/assets/typescript/Sakura/Notifications.ts
Normal file
51
resources/assets/typescript/Sakura/Notifications.ts
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
namespace Sakura
|
||||||
|
{
|
||||||
|
export class Notifications
|
||||||
|
{
|
||||||
|
private static Client: AJAX;
|
||||||
|
private static IntervalContainer: number;
|
||||||
|
public static DisplayMethod: Function = (alert: INotification) => {
|
||||||
|
console.log(alert);
|
||||||
|
};
|
||||||
|
|
||||||
|
public static Init(): void
|
||||||
|
{
|
||||||
|
this.Client = new AJAX;
|
||||||
|
this.Client.SetUrl("/notifications");
|
||||||
|
this.Client.AddCallback(200, (client: AJAX) => {
|
||||||
|
Notifications.Load(<INotification[]>client.JSON());
|
||||||
|
});
|
||||||
|
this.Poll();
|
||||||
|
this.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Poll(): void
|
||||||
|
{
|
||||||
|
this.Client.Start(HTTPMethod.GET);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Start(): void
|
||||||
|
{
|
||||||
|
this.IntervalContainer = setInterval(() => {
|
||||||
|
if (document.hidden) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Notifications.Poll();
|
||||||
|
}, 5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Stop(): void
|
||||||
|
{
|
||||||
|
this.Client.Stop();
|
||||||
|
clearInterval(this.IntervalContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Load(alerts: INotification[]): void
|
||||||
|
{
|
||||||
|
for (var i in alerts) {
|
||||||
|
this.DisplayMethod(alerts[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
28
resources/assets/typescript/Yuuno/Notifications.ts
Normal file
28
resources/assets/typescript/Yuuno/Notifications.ts
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/// <reference path="../Sakura/INotification.ts" />
|
||||||
|
|
||||||
|
namespace Yuuno
|
||||||
|
{
|
||||||
|
export class Notifications
|
||||||
|
{
|
||||||
|
private static Container;
|
||||||
|
|
||||||
|
public static RegisterDisplay(): void
|
||||||
|
{
|
||||||
|
this.Container = new Sakura.DOM('notifications', Sakura.DOMSelector.ID);
|
||||||
|
Sakura.Notifications.DisplayMethod = this.Display;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Display(alert: Sakura.INotification): void
|
||||||
|
{
|
||||||
|
var id = 'yuuno-alert-' + Date.now(),
|
||||||
|
container = Sakura.DOM.Create('div', 'notification-enter', id),
|
||||||
|
icon = Sakura.DOM.Create('div', 'notification-icon'),
|
||||||
|
inner = Sakura.DOM.Create('div', 'notification-content'),
|
||||||
|
title = Sakura.DOM.Create('div', 'notification-title'),
|
||||||
|
text = Sakura.DOM.Create('div', 'notification-text'),
|
||||||
|
close = Sakura.DOM.Create('div', 'notification-close'),
|
||||||
|
closeIcon = Sakura.DOM.Create('div'),
|
||||||
|
clear = Sakura.DOM.Create('div');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ namespace Yuuno
|
||||||
public static Startup()
|
public static Startup()
|
||||||
{
|
{
|
||||||
Sakura.Main.Startup();
|
Sakura.Main.Startup();
|
||||||
|
Notifications.RegisterDisplay();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,37 +114,6 @@ function notifyOpen(id: string): void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request notifications
|
|
||||||
function notifyRequest(session: string): void {
|
|
||||||
// Check if the document isn't hidden
|
|
||||||
if (document.hidden) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create AJAX object
|
|
||||||
var get = new Sakura.AJAX();
|
|
||||||
get.SetUrl('/notifications');
|
|
||||||
|
|
||||||
// Add callbacks
|
|
||||||
get.AddCallback(200, () => {
|
|
||||||
// Assign the parsed JSON
|
|
||||||
var data: Notification = JSON.parse(get.Response());
|
|
||||||
|
|
||||||
// Check if nothing went wrong
|
|
||||||
if ((typeof data).toLowerCase() === 'undefined') {
|
|
||||||
// Inform the user
|
|
||||||
throw "No or invalid data was returned";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create an object for every notification
|
|
||||||
for (var id in data) {
|
|
||||||
notifyUI(data[id]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
get.Start(Sakura.HTTPMethod.GET);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show the full page busy window
|
// Show the full page busy window
|
||||||
function ajaxBusyView(show: boolean, message: string = null, type: string = null): void {
|
function ajaxBusyView(show: boolean, message: string = null, type: string = null): void {
|
||||||
// Get elements
|
// Get elements
|
||||||
|
|
|
@ -39,9 +39,6 @@
|
||||||
<div class="centreAlign">
|
<div class="centreAlign">
|
||||||
<input class="inputStyling" type="password" id="registerPassword" name="password" onkeyup="registerVarCheck(this.id, 'password');" placeholder="Using special characters is recommended">
|
<input class="inputStyling" type="password" id="registerPassword" name="password" onkeyup="registerVarCheck(this.id, 'password');" placeholder="Using special characters is recommended">
|
||||||
</div>
|
</div>
|
||||||
<div class="subLinks centreAlign">
|
|
||||||
<input class="inputStyling" name="tos" type="checkbox" id="registerToS"><label for="registerToS">I agree to the <a class="default" href="{{ route('info.terms') }}" target="_blank">Terms of Service</a>.
|
|
||||||
</div>
|
|
||||||
<div class="centreAlign">
|
<div class="centreAlign">
|
||||||
<input class="inputStyling" type="submit" name="submit" value="Register" id="registerAccBtn">
|
<input class="inputStyling" type="submit" name="submit" value="Register" id="registerAccBtn">
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -167,6 +167,7 @@
|
||||||
UserNameMaxLength: {{ config('user.name_max') }},
|
UserNameMaxLength: {{ config('user.name_max') }},
|
||||||
PasswordMinEntropy: {{ config('user.pass_min_entropy') }},
|
PasswordMinEntropy: {{ config('user.pass_min_entropy') }},
|
||||||
LoggedIn: {{ user.isActive ? 'true' : 'false' }},
|
LoggedIn: {{ user.isActive ? 'true' : 'false' }},
|
||||||
|
UserId: {{ user.id }},
|
||||||
SessionId: "{{ session_id() }}",
|
SessionId: "{{ session_id() }}",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -175,12 +176,6 @@
|
||||||
{% if config('dev.show_changelog', true) and stats %}
|
{% if config('dev.show_changelog', true) and stats %}
|
||||||
Sakura.Changelog.Build(new Sakura.DOM('indexPanel', Sakura.DOMSelector.ID));
|
Sakura.Changelog.Build(new Sakura.DOM('indexPanel', Sakura.DOMSelector.ID));
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
notifyRequest(Sakura.Config.SessionId);
|
|
||||||
|
|
||||||
setInterval(function() {
|
|
||||||
notifyRequest(Sakura.Config.SessionId);
|
|
||||||
}, 60000);
|
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -4,9 +4,58 @@
|
||||||
|
|
||||||
{% set noUserpage = profile.userPage|length < 1 %}
|
{% set noUserpage = profile.userPage|length < 1 %}
|
||||||
|
|
||||||
{% set profileView = noUserpage and profileView == 'index' ? 'comments' : profileView %}
|
{% set title = profileHidden ? 'User not found!' : 'Profile of ' ~ profile.username %}
|
||||||
|
|
||||||
{% set title %}{% if profileHidden %}User not found!{% else %}Profile of {{ profile.username }}{% endif %}{% endset %}
|
{% set youtubeIsChannelId = profile.youtube|slice(0, 2) == 'UC' and profile.youtube|length == 24 %}
|
||||||
|
|
||||||
|
{% set fields = {
|
||||||
|
"website": {
|
||||||
|
"title": "Website",
|
||||||
|
"value": profile.website,
|
||||||
|
"link": "%s",
|
||||||
|
},
|
||||||
|
"twitter": {
|
||||||
|
"title": "Twitter",
|
||||||
|
"value": profile.twitter,
|
||||||
|
"link": "https://twitter.com/%s",
|
||||||
|
"disp": "@%s",
|
||||||
|
},
|
||||||
|
"github": {
|
||||||
|
"title": "GitHub",
|
||||||
|
"value": profile.github,
|
||||||
|
"link": "https://github.com/%s",
|
||||||
|
},
|
||||||
|
"skype": {
|
||||||
|
"title": "Skype",
|
||||||
|
"value": profile.skype,
|
||||||
|
"link": "skype:%s?userinfo",
|
||||||
|
},
|
||||||
|
"discord": {
|
||||||
|
"title": "Discord",
|
||||||
|
"value": profile.discord,
|
||||||
|
},
|
||||||
|
"youtube": {
|
||||||
|
"title": "YouTube",
|
||||||
|
"value": profile.youtube,
|
||||||
|
"link": "https://youtube.com/" ~ (youtubeIsChannelId ? 'channel/' : '') ~ "%s",
|
||||||
|
"disp": youtubeIsChannelId ? profile.username ~ "'s channel" : "%s",
|
||||||
|
},
|
||||||
|
"steam": {
|
||||||
|
"title": "Steam",
|
||||||
|
"value": profile.steam,
|
||||||
|
"link": "https://steamcommunity.com/id/%s",
|
||||||
|
},
|
||||||
|
"osu": {
|
||||||
|
"title": "osu!",
|
||||||
|
"value": profile.osu,
|
||||||
|
"link": "https://osu.ppy.sh/u/%s",
|
||||||
|
},
|
||||||
|
"lastfm": {
|
||||||
|
"title": "Last.fm",
|
||||||
|
"value": profile.lastfm,
|
||||||
|
"link": "http://last.fm/user/%s",
|
||||||
|
},
|
||||||
|
} %}
|
||||||
|
|
||||||
{% block js %}
|
{% block js %}
|
||||||
{% if not profileHidden %}
|
{% if not profileHidden %}
|
||||||
|
@ -102,10 +151,9 @@
|
||||||
{% if not noUserpage %}
|
{% if not noUserpage %}
|
||||||
<a class="fa fa-file-text-o" title="View {{ profile.username }}'s user page" href="#_userpage" onclick="profileMode('userpage');"></a>
|
<a class="fa fa-file-text-o" title="View {{ profile.username }}'s user page" href="#_userpage" onclick="profileMode('userpage');"></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{#<a class="fa fa-list" title="View {{ profile.username }}'s topics" href="#_topics" onclick="profileMode('topics');"></a>
|
<a class="fa fa-list" title="View {{ profile.username }}'s topics" href="#_topics" onclick="profileMode('topics');"></a>
|
||||||
<a class="fa fa-reply" title="View {{ profile.username }}'s posts" href="#_posts" onclick="profileMode('posts');"></a>#}
|
<a class="fa fa-reply" title="View {{ profile.username }}'s posts" href="#_posts" onclick="profileMode('posts');"></a>
|
||||||
<a class="fa fa-star" title="View {{ profile.username }}'s friends" href="#_friends" onclick="profileMode('friends');"></a>
|
<a class="fa fa-star" title="View {{ profile.username }}'s friends" href="#_friends" onclick="profileMode('friends');"></a>
|
||||||
{#<a class="fa fa-users" title="View {{ profile.username }}'s groups" href="#_groups" onclick="profileMode('groups');"></a>#}
|
|
||||||
<a class="fa fa-comments-o" title="View {{ profile.username }}'s profile comments" href="#_comments" onclick="profileMode('comments');"></a>
|
<a class="fa fa-comments-o" title="View {{ profile.username }}'s profile comments" href="#_comments" onclick="profileMode('comments');"></a>
|
||||||
</div>
|
</div>
|
||||||
{% if user.isActive %}
|
{% if user.isActive %}
|
||||||
|
@ -164,25 +212,21 @@
|
||||||
{% if profile.profileFields or user.permission(constant('Sakura\\Perms\\Manage::USE_MANAGE'), constant('Sakura\\Perms::MANAGE')) %}
|
{% if profile.profileFields or user.permission(constant('Sakura\\Perms\\Manage::USE_MANAGE'), constant('Sakura\\Perms::MANAGE')) %}
|
||||||
{% if user.isActive %}
|
{% if user.isActive %}
|
||||||
<table style="width: 100%;">
|
<table style="width: 100%;">
|
||||||
{% for name,field in profile.profileFields %}
|
{% for id, data in fields %}
|
||||||
<tr>
|
{% if data.value != null %}
|
||||||
<td style="text-align: left; font-weight: bold;">
|
<tr>
|
||||||
{{ field.name }}
|
<td style="text-align: left; font-weight: bold;">
|
||||||
</td>
|
{{ data.title }}
|
||||||
<td style="text-align: right;">
|
</td>
|
||||||
{% if name == 'youtube' %}
|
<td style="text-align: right;">
|
||||||
<a href="https://youtube.com/{% if field.youtubetype == true %}channel{% else %}user{% endif %}/{{ field.value }}" class="default">{% if field.youtubetype == true %}{{ profile.username }}'s Channel{% else %}{{ field.value }}{% endif %}</a>
|
{% if data.link %}
|
||||||
{% else %}
|
<a href="{{ data.link|format(data.value) }}" class="default">{{ (data.disp ? data.disp : '%s')|format(data.value) }}</a>
|
||||||
{% if field.islink %}
|
{% else %}
|
||||||
<a href="{{ field.link }}" class="default">
|
{{ (data.disp ? data.disp : '%s')|format(data.value) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{{ field.value }}
|
</td>
|
||||||
{% if field.islink %}
|
</tr>
|
||||||
</a>
|
{% endif %}
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% if user.permission(constant('Sakura\\Perms\\Manage::USE_MANAGE'), constant('Sakura\\Perms::MANAGE')) %}
|
{% if user.permission(constant('Sakura\\Perms\\Manage::USE_MANAGE'), constant('Sakura\\Perms::MANAGE')) %}
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -3,9 +3,8 @@
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"noImplicitAny": false,
|
"noImplicitAny": false,
|
||||||
"removeComments": true,
|
"removeComments": true,
|
||||||
"preserveConstEnums": true
|
"preserveConstEnums": true,
|
||||||
},
|
"moduleResolution": "node",
|
||||||
"exclude": [
|
"rootDir": "resources/assets/typescript"
|
||||||
"public"
|
}
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue