mirror of
https://github.com/Poniverse/Pony.fm.git
synced 2024-11-21 20:48:00 +01:00
Added announcement system
This commit is contained in:
parent
fa7e04aee9
commit
ec8b64f494
10 changed files with 327 additions and 2 deletions
45
app/Http/Controllers/Api/Web/AnnouncementsController.php
Normal file
45
app/Http/Controllers/Api/Web/AnnouncementsController.php
Normal file
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Pony.fm - A community for pony fan music.
|
||||
* Copyright (C) 2016 Josef Citrine
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Poniverse\Ponyfm\Http\Controllers\Api\Web;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Poniverse\Ponyfm\Http\Controllers\Controller;
|
||||
use Poniverse\Ponyfm\Models\Announcement;
|
||||
use Response;
|
||||
|
||||
class AnnouncementsController extends Controller {
|
||||
public function getIndex() {
|
||||
$currentDate = Carbon::now();
|
||||
|
||||
$query = Announcement::whereNotNull('start_time')
|
||||
->whereNotNull('end_time')
|
||||
->where('start_time', '<', $currentDate)
|
||||
->where('end_time', '>', $currentDate)
|
||||
->orderBy('start_time', 'desc');
|
||||
|
||||
$announcement = $query->first();
|
||||
|
||||
return Response::json(
|
||||
["announcement" => $announcement],
|
||||
200
|
||||
);
|
||||
}
|
||||
}
|
37
app/Models/Announcement.php
Normal file
37
app/Models/Announcement.php
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Pony.fm - A community for pony fan music.
|
||||
* Copyright (C) 2016 Josef Citrine
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Poniverse\Ponyfm\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Announcement extends Model {
|
||||
protected $table = 'announcements';
|
||||
|
||||
protected $casts = [
|
||||
'links' => 'array',
|
||||
'tracks' => 'array'
|
||||
];
|
||||
|
||||
const TYPE_GENERIC = 1;
|
||||
const TYPE_WARNING_ALERT = 2;
|
||||
const TYPE_SERIOUS_ALERT = 3;
|
||||
const TYPE_CUSTOM = 4;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateAnnouncementsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('announcements', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->string('title');
|
||||
$table->text('text_content', 65535)->nullable();
|
||||
$table->integer('announcement_type_id')->unsigned()->nullable();
|
||||
$table->json('links')->nullable();
|
||||
$table->json('tracks')->nullable();
|
||||
$table->string('css_class')->nullable();
|
||||
$table->string('template_file')->nullable();
|
||||
$table->dateTime("start_time")->nullable();
|
||||
$table->dateTime("end_time")->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::drop('announcements');
|
||||
}
|
||||
}
|
|
@ -1,4 +1,7 @@
|
|||
<div class="dashboard stretch-to-bottom">
|
||||
<section class="announce-wrapper" ng-class="announceWrapperClass">
|
||||
<div id="announcement" ng-show="announcement != null" ng-class="announcementClass"></div>
|
||||
</section>
|
||||
<section class="recent-tracks">
|
||||
<h1>
|
||||
<a href="/tracks"><i class="fa fa-music"></i> see more</a>
|
||||
|
|
12
public/templates/partials/alert-announcement.html
Normal file
12
public/templates/partials/alert-announcement.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
<div class="announce-content">
|
||||
<h2>{{ ::announcement.title }}</h2>
|
||||
<p marked="announcement.text_content"></p>
|
||||
</div>
|
||||
<div class="announce-actions">
|
||||
<span ng-repeat="link in announcement.links">
|
||||
<a ng-href="{{ ::link.url }}" target="_blank">{{ ::link.title }}</a>
|
||||
</span>
|
||||
<a href="#" ng-click="announcement.dontShowAgain()">Don't show again</a>
|
||||
</div>
|
||||
<a href="#" class="dismiss-button" ng-click="announcement.dismiss()"><i class="fa fa-times"></i></a>
|
||||
<i class="fa fa-exclamation-triangle announce-bg-icon" aria-hidden="true"></i>
|
12
public/templates/partials/default-announcement.html
Normal file
12
public/templates/partials/default-announcement.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
<div class="announce-content">
|
||||
<h2>{{ ::announcement.title }}</h2>
|
||||
<p marked="announcement.text_content"></p>
|
||||
</div>
|
||||
<div class="announce-actions">
|
||||
<span ng-repeat="link in announcement.links">
|
||||
<a ng-href="{{ ::link.url }}" target="_blank">{{ ::link.title }}</a>
|
||||
</span>
|
||||
<a href="#" ng-click="announcement.dontShowAgain()">Don't show again</a>
|
||||
</div>
|
||||
<a href="#" class="dismiss-button" ng-click="announcement.dismiss()"><i class="fa fa-times"></i></a>
|
||||
<i class="fa fa-info-circle announce-bg-icon" aria-hidden="true"></i>
|
|
@ -20,13 +20,49 @@ window.pfm.preloaders['dashboard'] = [
|
|||
]
|
||||
|
||||
module.exports = angular.module('ponyfm').controller "dashboard", [
|
||||
'$scope', 'dashboard', 'auth', '$http'
|
||||
($scope, dashboard, auth, $http) ->
|
||||
'$scope', 'dashboard', 'auth', '$http', 'announcements', '$compile'
|
||||
($scope, dashboard, auth, $http, announcements, $compile) ->
|
||||
|
||||
$scope.recentTracks = null
|
||||
$scope.popularTracks = null
|
||||
$scope.announcementClass = 'disabled'
|
||||
$scope.announceWrapperClass = 'disabled'
|
||||
|
||||
$scope.loadAnnouncementTemplate = (url) ->
|
||||
$http.get('/templates/' + url).success (templateContent) ->
|
||||
compiledHtml = $compile(templateContent)($scope)
|
||||
$('#announcement').append(compiledHtml)
|
||||
|
||||
dashboard.refresh().done (res) ->
|
||||
$scope.recentTracks = res.recent_tracks
|
||||
$scope.popularTracks = res.popular_tracks
|
||||
|
||||
announcements.refresh().done (ann) ->
|
||||
$scope.announcement = ann
|
||||
if $scope.announcement != null
|
||||
if parseInt($.cookie('hide-announcement')) != parseInt($scope.announcement.id)
|
||||
$scope.announcement.dismiss = () ->
|
||||
$scope.announceWrapperClass = 'disabled'
|
||||
|
||||
$scope.announcement.dontShowAgain = () ->
|
||||
$scope.announcement.dismiss()
|
||||
$.cookie('hide-announcement', $scope.announcement.id)
|
||||
|
||||
switch $scope.announcement.announcement_type_id
|
||||
when 1
|
||||
$scope.announcementClass = "simple-announce " + $scope.announcement.css_class
|
||||
$scope.announceWrapperClass = null
|
||||
$scope.loadAnnouncementTemplate('partials/default-announcement.html')
|
||||
when 2
|
||||
$scope.announcementClass = "alert-announce " + $scope.announcement.css_class
|
||||
$scope.announceWrapperClass = null
|
||||
$scope.loadAnnouncementTemplate('partials/alert-announcement.html')
|
||||
when 3
|
||||
$scope.announcementClass = "serious-alert-announce " + $scope.announcement.css_class
|
||||
$scope.announceWrapperClass = null
|
||||
$scope.loadAnnouncementTemplate('partials/alert-announcement.html')
|
||||
when 4
|
||||
$scope.announcementClass = $scope.announcement.css_class
|
||||
$scope.announceWrapperClass = null
|
||||
$scope.loadAnnouncementTemplate($scope.announcement.template_url)
|
||||
]
|
||||
|
|
32
resources/assets/scripts/app/services/announcements.coffee
Normal file
32
resources/assets/scripts/app/services/announcements.coffee
Normal file
|
@ -0,0 +1,32 @@
|
|||
# Pony.fm - A community for pony fan music.
|
||||
# Copyright (C) 2016 Josef Citrine
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module.exports = angular.module('ponyfm').factory('announcements', [
|
||||
'$rootScope', '$http'
|
||||
($rootScope, $http) ->
|
||||
def = null
|
||||
|
||||
self =
|
||||
refresh: (force) ->
|
||||
force = force || false
|
||||
return def if !force && def
|
||||
def = new $.Deferred()
|
||||
$http.get('/api/web/announcements').success (announcementResponse) ->
|
||||
def.resolve(announcementResponse.announcement)
|
||||
def.promise()
|
||||
|
||||
self
|
||||
])
|
107
resources/assets/styles/dashboard.less
vendored
107
resources/assets/styles/dashboard.less
vendored
|
@ -94,6 +94,113 @@
|
|||
width: 37.5%;
|
||||
}
|
||||
|
||||
.announce-wrapper {
|
||||
width: 100%;
|
||||
margin-bottom: 5px;
|
||||
|
||||
&.disabled {
|
||||
margin: 0;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#announcement {
|
||||
width: 100%;
|
||||
box-shadow: 0 1px 4px rgba(0,0,0,0.12), 0 2px 3px rgba(0,0,0,0.24);
|
||||
border-radius: 3px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
max-width: 1200px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
|
||||
.announce-content {
|
||||
padding: 10px;
|
||||
overflow: hidden;
|
||||
|
||||
@media (max-width: 720px) {
|
||||
padding-left: 10px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.announce-actions {
|
||||
padding: 5px 15px 15px;
|
||||
position: relative;
|
||||
background: inherit;
|
||||
z-index: 2;
|
||||
|
||||
&.border {
|
||||
border-top: 1px solid rgba(160,160,160,0.2);
|
||||
}
|
||||
|
||||
a {
|
||||
margin-right: 20px;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
&.simple-announce {
|
||||
.announce-content {
|
||||
padding-left: 75px;
|
||||
}
|
||||
}
|
||||
|
||||
&.alert-announce, &.serious-alert-announce {
|
||||
.announce-content {
|
||||
padding-left: 95px;
|
||||
}
|
||||
}
|
||||
|
||||
&.alert-announce {
|
||||
background: #f57f17;
|
||||
}
|
||||
|
||||
&.serious-alert-announce {
|
||||
background: #d84315
|
||||
}
|
||||
|
||||
&.simple-announce {
|
||||
background: #894d8f;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dismiss-button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: 6px 20px;
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
h2, p, a {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.announce-bg-icon {
|
||||
color: #fff;
|
||||
opacity: 0.6;
|
||||
top: -13px;
|
||||
left: -20px;
|
||||
position: absolute;
|
||||
font-size: 100px;
|
||||
transform: rotate(-9deg);
|
||||
z-index: 1;
|
||||
|
||||
@media (max-width: 720px) {
|
||||
opacity: 0.1;
|
||||
right: 0;
|
||||
left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.news {
|
||||
width: 25%;
|
||||
|
||||
|
|
|
@ -116,6 +116,8 @@ Route::group(['prefix' => 'api/web'], function () {
|
|||
|
||||
Route::get('/dashboard', 'Api\Web\DashboardController@getIndex');
|
||||
|
||||
Route::get('/announcements', 'Api\Web\AnnouncementsController@getIndex');
|
||||
|
||||
Route::group(['middleware' => 'auth'], function () {
|
||||
Route::post('/tracks/upload', 'Api\Web\TracksController@postUpload');
|
||||
Route::get('/tracks/{id}/upload-status', 'Api\Web\TracksController@getUploadStatus');
|
||||
|
|
Loading…
Reference in a new issue