This commit is contained in:
flash 2016-08-03 19:47:46 +02:00
parent 0dc204fcb3
commit 3d8c30e8b6
32 changed files with 178 additions and 89 deletions

View file

@ -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');
return json_encode($object, $operators);

View file

@ -36,15 +36,15 @@ class Notification
if ($data) {
$data = $data[0];
$this->id = $data->alert_id;
$this->user = $data->user_id;
$this->time = $data->alert_timestamp;
$this->id = intval($data->alert_id);
$this->user = intval($data->user_id);
$this->time = intval($data->alert_timestamp);
$this->read = intval($data->alert_read) !== 0;
$this->title = $data->alert_title;
$this->text = $data->alert_text;
$this->link = $data->alert_link;
$this->image = $data->alert_img;
$this->timeout = $data->alert_timeout;
$this->timeout = intval($data->alert_timeout);
}
}

View file

@ -214,13 +214,6 @@ class User
*/
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.
*
@ -369,7 +362,6 @@ class User
$this->skype = $userRow->user_skype;
$this->discord = $userRow->user_discord;
$this->youtube = $userRow->user_youtube;
$this->youtubeType = intval($userRow->user_youtube_type);
$this->steam = $userRow->user_steam;
$this->osu = $userRow->user_osu;
$this->lastfm = $userRow->user_lastfm;
@ -1089,7 +1081,7 @@ class User
$alerts = [];
foreach ($alertIds as $alertId) {
$alerts[$alertId] = new Notification($alertId);
$alerts[] = new Notification($alertId);
}
return $alerts;

View file

@ -47,9 +47,6 @@ class MoveOptionsAndProfileIntoUsers extends Migration
->nullable()
->default(null);
$table->tinyInteger('user_youtube_type')
->default(0);
$table->string('user_steam', 255)
->nullable()
->default(null);
@ -82,7 +79,6 @@ class MoveOptionsAndProfileIntoUsers extends Migration
'user_skype',
'user_discord',
'user_youtube',
'user_youtube_type',
'user_steam',
'user_osu',
'user_lastfm',

View file

@ -7,9 +7,9 @@ elixir(function(mix) {
mix
.less('aitemu/master.less', 'public/css/aitemu.css')
.less('yuuno/master.less', 'public/css/yuuno.css')
.typescript('app/**/*.ts', 'public/js/app.js')
.typescript('aitemu/**/*.ts', 'public/js/aitemu.js')
.typescript('yuuno/**/*.ts', 'public/js/yuuno.js')
.typescript('Sakura/**/*.ts', 'public/js/app.js')
.typescript('Aitemu/**/*.ts', 'public/js/aitemu.js')
.typescript('Yuuno/**/*.ts', 'public/js/yuuno.js')
.scripts([
nodePath + 'turbolinks/dist/turbolinks.js',
], 'public/js/libraries.js');

View file

@ -3,6 +3,7 @@ namespace Sakura
export class Config
{
public static Revision: number = 0;
public static UserId: number = 0;
public static SessionId: string = "";
public static UserNameMinLength: number = 3;
public static UserNameMaxLength: number = 16;

View 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;
}
}

View file

@ -6,6 +6,7 @@ namespace Sakura
console.log(this.Supported());
TimeAgo.Init();
Friend.Init();
Notifications.Init();
}
public static Supported(): boolean {

View 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]);
}
}
}
}

View 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');
}
}
}

View file

@ -5,6 +5,7 @@ namespace Yuuno
public static Startup()
{
Sakura.Main.Startup();
Notifications.RegisterDisplay();
}
}
}

View file

@ -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
function ajaxBusyView(show: boolean, message: string = null, type: string = null): void {
// Get elements

View file

@ -39,9 +39,6 @@
<div class="centreAlign">
<input class="inputStyling" type="password" id="registerPassword" name="password" onkeyup="registerVarCheck(this.id, 'password');" placeholder="Using special characters is recommended">
</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">
<input class="inputStyling" type="submit" name="submit" value="Register" id="registerAccBtn">
</div>

View file

@ -167,6 +167,7 @@
UserNameMaxLength: {{ config('user.name_max') }},
PasswordMinEntropy: {{ config('user.pass_min_entropy') }},
LoggedIn: {{ user.isActive ? 'true' : 'false' }},
UserId: {{ user.id }},
SessionId: "{{ session_id() }}",
});
@ -175,12 +176,6 @@
{% if config('dev.show_changelog', true) and stats %}
Sakura.Changelog.Build(new Sakura.DOM('indexPanel', Sakura.DOMSelector.ID));
{% endif %}
notifyRequest(Sakura.Config.SessionId);
setInterval(function() {
notifyRequest(Sakura.Config.SessionId);
}, 60000);
</script>
</body>
</html>

View file

@ -4,9 +4,58 @@
{% 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 %}
{% if not profileHidden %}
@ -102,10 +151,9 @@
{% if not noUserpage %}
<a class="fa fa-file-text-o" title="View {{ profile.username }}'s user page" href="#_userpage" onclick="profileMode('userpage');"></a>
{% endif %}
{#<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-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-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>
</div>
{% if user.isActive %}
@ -164,25 +212,21 @@
{% if profile.profileFields or user.permission(constant('Sakura\\Perms\\Manage::USE_MANAGE'), constant('Sakura\\Perms::MANAGE')) %}
{% if user.isActive %}
<table style="width: 100%;">
{% for name,field in profile.profileFields %}
<tr>
<td style="text-align: left; font-weight: bold;">
{{ field.name }}
</td>
<td style="text-align: right;">
{% if name == 'youtube' %}
<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>
{% else %}
{% if field.islink %}
<a href="{{ field.link }}" class="default">
{% for id, data in fields %}
{% if data.value != null %}
<tr>
<td style="text-align: left; font-weight: bold;">
{{ data.title }}
</td>
<td style="text-align: right;">
{% if data.link %}
<a href="{{ data.link|format(data.value) }}" class="default">{{ (data.disp ? data.disp : '%s')|format(data.value) }}</a>
{% else %}
{{ (data.disp ? data.disp : '%s')|format(data.value) }}
{% endif %}
{{ field.value }}
{% if field.islink %}
</a>
{% endif %}
{% endif %}
</td>
</tr>
</td>
</tr>
{% endif %}
{% endfor %}
{% if user.permission(constant('Sakura\\Perms\\Manage::USE_MANAGE'), constant('Sakura\\Perms::MANAGE')) %}
<tr>

View file

@ -3,9 +3,8 @@
"module": "commonjs",
"noImplicitAny": false,
"removeComments": true,
"preserveConstEnums": true
},
"exclude": [
"public"
]
"preserveConstEnums": true,
"moduleResolution": "node",
"rootDir": "resources/assets/typescript"
}
}