diff --git a/app/Http/Controllers/Api/Web/AnnouncementsController.php b/app/Http/Controllers/Api/Web/AnnouncementsController.php new file mode 100644 index 00000000..caf974f4 --- /dev/null +++ b/app/Http/Controllers/Api/Web/AnnouncementsController.php @@ -0,0 +1,45 @@ +. + */ + +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 + ); + } +} diff --git a/app/Models/Announcement.php b/app/Models/Announcement.php new file mode 100644 index 00000000..d8791f16 --- /dev/null +++ b/app/Models/Announcement.php @@ -0,0 +1,37 @@ +. + */ + +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; +} diff --git a/database/migrations/2016_11_10_220126_create_announcements_table.php b/database/migrations/2016_11_10_220126_create_announcements_table.php new file mode 100644 index 00000000..310b513b --- /dev/null +++ b/database/migrations/2016_11_10_220126_create_announcements_table.php @@ -0,0 +1,39 @@ +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'); + } +} diff --git a/public/templates/dashboard/index.html b/public/templates/dashboard/index.html index 849881de..b4739d7e 100644 --- a/public/templates/dashboard/index.html +++ b/public/templates/dashboard/index.html @@ -1,4 +1,7 @@
+
+
+

see more diff --git a/public/templates/partials/alert-announcement.html b/public/templates/partials/alert-announcement.html new file mode 100644 index 00000000..a19801f1 --- /dev/null +++ b/public/templates/partials/alert-announcement.html @@ -0,0 +1,12 @@ +
+

{{ ::announcement.title }}

+

+
+ + + diff --git a/public/templates/partials/default-announcement.html b/public/templates/partials/default-announcement.html new file mode 100644 index 00000000..e9934e78 --- /dev/null +++ b/public/templates/partials/default-announcement.html @@ -0,0 +1,12 @@ +
+

{{ ::announcement.title }}

+

+
+ + + diff --git a/resources/assets/scripts/app/controllers/dashboard.coffee b/resources/assets/scripts/app/controllers/dashboard.coffee index 2ed5567c..3a3e17c7 100644 --- a/resources/assets/scripts/app/controllers/dashboard.coffee +++ b/resources/assets/scripts/app/controllers/dashboard.coffee @@ -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) ] diff --git a/resources/assets/scripts/app/services/announcements.coffee b/resources/assets/scripts/app/services/announcements.coffee new file mode 100644 index 00000000..0a1d4b18 --- /dev/null +++ b/resources/assets/scripts/app/services/announcements.coffee @@ -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 . + +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 +]) diff --git a/resources/assets/styles/dashboard.less b/resources/assets/styles/dashboard.less index d0f86965..810518c8 100644 --- a/resources/assets/styles/dashboard.less +++ b/resources/assets/styles/dashboard.less @@ -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%; diff --git a/routes/web.php b/routes/web.php index 284d0b9e..d56eed27 100644 --- a/routes/web.php +++ b/routes/web.php @@ -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');