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