Merge branch 'socket_fixes'

This commit is contained in:
Fergal Moran
2016-06-03 20:52:26 +01:00
16 changed files with 649 additions and 258 deletions

View File

@@ -15,7 +15,6 @@
"angular-resource": ">=1.2.*",
"angular-sanitize": ">=1.2.*",
"angular-smilies": "~1.2.0",
"angular-socket-io": "~0.6.0",
"angular-ui-router": "~0.2.10",
"angulartics": "~0.18.0",
"bootstrap": "~3.3.5",
@@ -41,7 +40,10 @@
"zeroclipboard": "~2.2.0",
"ng-clip": "~0.2.6",
"satellizer": "~0.13.3",
"ngInfiniteScroll": "1.2.1"
"ngInfiniteScroll": "1.2.1",
"angular-socket-io": "^0.7.0",
"socket.io-client": "^1.4.6",
"angular-toastr": "^1.7.0"
},
"devDependencies": {
"angular-mocks": ">=1.2.*",

View File

@@ -19,6 +19,7 @@ angular.module('dssWebApp', [
'angular-jwt',
'angular-smilies',
'satellizer',
'toastr',
'angulartics.google.analytics'
])
.config(function ($stateProvider, $sceDelegateProvider, $httpProvider, $urlRouterProvider, $locationProvider, $provide, $authProvider,
@@ -85,12 +86,11 @@ angular.module('dssWebApp', [
$rootScope.isPlaying = false;
$rootScope.setCurrentUser = function (user) {
console.log('Current user', user);
$rootScope.currentUser = user;
};
$rootScope.connectSockets = function () {
SocketService.connectSocket(Session.getSession());
SocketService.registerHandler('site:broadcast', function (data) {
//SocketService.connectSocket(Session.getSession());
SocketService.on('socket:site:broadcast', function (data) {
console.log(data);
$.notify({
message: data,

View File

@@ -4,6 +4,7 @@
@fa-font-path: '/bower_components/font-awesome/fonts';
// injector
@import 'components/chatbar/chatbar.less';
@import 'components/comments/comments.less';
@import 'components/footer/footer.less';
@import 'components/messagepopup/messagepopup.less';
@@ -24,61 +25,83 @@
// endinjector
#page-content {
min-height: 894px;
min-height: 894px;
}
.list-nostyle {
list-style: none outside none;
margin: 0;
list-style: none outside none;
margin: 0;
}
.list-horiz li {
float: left;
list-style-type: none;
position: relative;
padding-right: 20px;
float: left;
list-style-type: none;
position: relative;
padding-right: 20px;
}
.truncate {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.non-url-button {
cursor: default;
cursor: default;
}
.chat-talk {
padding-top: 5px;
padding-top: 5px;
}
.slimScrollDiv {
padding-left: 5px;
padding-right: 5px;
padding-left: 5px;
padding-right: 5px;
}
.sidebar-alt-visible-lg #sidebar-alt {
width: 300px !important;
width: 300px !important;
}
.sidebar-alt-visible-lg #main-container {
margin-right: 300px !important;
margin-right: 300px !important;
}
.sidebar-alt-visible-lg.header-fixed-top header.navbar-fixed-top, .sidebar-alt-visible-lg.header-fixed-bottom header.navbar-fixed-bottom,
.sidebar-alt-visible-lg.footer-fixed #main-container #page-content + footer {
right: 300px !important;
right: 300px !important;
}
.sidebar-content {
width: 100% !important;
width: 100% !important;
}
.search-result-image{
width: 32px;
height: 32px;
.search-result-image {
width: 32px;
height: 32px;
}
.fa-1-3x {
font-size: 1.3em;
font-size: 1.3em;
}
/*
.select2-choices {
position: relative;
}
.ui-select-multiple input.ui-select-search {
width: 100% !important;
position: absolute;
}
*/
.override-text-align {
text-align: left !important;
}
h6.description {
font-weight: bold;
letter-spacing: 2px;
color: #999;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
padding-bottom: 5px;
}

View File

@@ -1,16 +1,17 @@
'use strict';
angular.module('dssWebApp')
.controller('ChatbarCtrl', function ($scope, $rootScope, $http, SocketService, SERVER_CONFIG, AUTH_EVENTS) {
.controller('ChatbarCtrl', function ($scope, $rootScope, $http, SocketService, SERVER_CONFIG, AUTH_EVENTS, toastr) {
console.log('ChatbarCtrl', $scope);
$scope.messages = [];
$scope.chatMessage = '';
function _registerChatHandler() {
console.log('Registering chat handler');
SocketService.registerHandler('chat', function (message) {
SocketService.on('chat', function (message) {
var data = JSON.parse(message);
console.log("Received chat message: " + data);
toastr.success(data);
$scope.$apply(function () {
$scope.messages.push(data);
$scope.chatMessage = '';
@@ -28,7 +29,7 @@ angular.module('dssWebApp')
$scope.postMessage = function () {
$http.post(SERVER_CONFIG.apiUrl + '/_chat/', {
user: 'Someone',
user: '2',
message: $scope.chatMessage
});
};

View File

@@ -1,48 +1,84 @@
<div id="sidebar-alt">
<div id="sidebar-alt-scroll">
<div class="sidebar-content">
<a class="sidebar-title">
<i class="fa fa-comments pull-right"></i> <strong>DSS</strong>Chat
</a>
<form id="sidebar-chat-form" class="chat-form" ng-submit="postMessage()">
<div class="input-group">
<input focus-on-change="chatMessage" class="form-control" ng-model="chatMessage"
placeholder="Type a message..">
<!--
<span class="input-group-addon" smilies-selector="chatMessage"
smilies-placement="right" smilies-title="Smilies">
</span>
-->
</div>
</form>
<div class="chat-talk">
<div class="slimScrollDiv" style="position: relative; overflow: hidden; width: auto; height: 100%;">
<ul class="media-list">
<li ng-repeat="message in messages" class="media animation-slideRight">
<div class="media-body">
<div class="media">
<a class="pull-left" href="#">
<img class="media-object img-circle " ng-src="{{message.image}}">
</a>
<div class="media-body" ng-bind-html="message.message | smilies">
</div>
<small class="text-muted">{{message.user}} |
<span time-ago="message.date" class="time-ago"></span>
</small>
</div>
</div>
</li>
</ul>
<div class="slimScrollBar"
style="width: 3px; position: absolute; top: 0px; opacity: 0.4; display: none; border-radius: 7px; z-index: 99; left: 1px; height: 210px; background: rgb(255, 255, 255);">
</div>
<div class="slimScrollRail"
style="width: 3px; height: 100%; position: absolute; top: 0px; display: none; border-radius: 7px; opacity: 0.2; z-index: 90; left: 1px; background: rgb(51, 51, 51);">
</div>
</div>
<div class="popup-box chat-popup popup-box-on" id="qnimate">
<div class="popup-head">
<div class="popup-head-left pull-left"><img
src="http://bootsnipp.com/img/avatars/bcf1c0d13e5500875fdd5a7e8ad9752ee16e7462.jpg"
alt="iamgurdeeposahan"> Gurdeep Osahan
</div>
<div class="popup-head-right pull-right">
<div class="btn-group">
<button class="chat-header-button" data-toggle="dropdown" type="button" aria-expanded="false">
<i class="glyphicon glyphicon-cog"></i></button>
<ul role="menu" class="dropdown-menu pull-right">
<li><a href="#">Media</a></li>
<li><a href="#">Block</a></li>
<li><a href="#">Clear Chat</a></li>
<li><a href="#">Email Chat</a></li>
</ul>
</div>
<button data-widget="remove" id="removeClass" class="chat-header-button pull-right" type="button"><i
class="glyphicon glyphicon-off"></i></button>
</div>
</div>
</div>
<div class="popup-messages">
<div class="direct-chat-messages">
<div class="chat-box-single-line">
<abbr class="timestamp">October 8th, 2015</abbr>
</div>
<!-- Message. Default to the left -->
<div class="direct-chat-msg doted-border">
<div class="direct-chat-info clearfix">
<span class="direct-chat-name pull-left">Osahan</span>
</div>
<!-- /.direct-chat-info -->
<img alt="message user image"
src="http://bootsnipp.com/img/avatars/bcf1c0d13e5500875fdd5a7e8ad9752ee16e7462.jpg"
class="direct-chat-img"><!-- /.direct-chat-img -->
<div class="direct-chat-text">
Hey bro, hows everything going ?
</div>
<div class="direct-chat-info clearfix">
<span class="direct-chat-timestamp pull-right">3.36 PM</span>
</div>
<div class="direct-chat-info clearfix">
<span class="direct-chat-img-reply-small pull-left">
</span>
<span class="direct-chat-reply-name">Singh</span>
</div>
<!-- /.direct-chat-text -->
</div>
<!-- /.direct-chat-msg -->
<div class="chat-box-single-line">
<abbr class="timestamp">October 9th, 2015</abbr>
</div>
<!-- Message. Default to the left -->
<div class="direct-chat-msg doted-border">
<div class="direct-chat-info clearfix">
<span class="direct-chat-name pull-left">Osahan</span>
</div>
<!-- /.direct-chat-info -->
<img alt="iamgurdeeposahan"
src="http://bootsnipp.com/img/avatars/bcf1c0d13e5500875fdd5a7e8ad9752ee16e7462.jpg"
class="direct-chat-img"><!-- /.direct-chat-img -->
<div class="direct-chat-text">
Hey bro, hows everything going ?
</div>
<div class="direct-chat-info clearfix">
<span class="direct-chat-timestamp pull-right">3.36 PM</span>
</div>
<div class="direct-chat-info clearfix">
<img alt="iamgurdeeposahan"
src="http://bootsnipp.com/img/avatars/bcf1c0d13e5500875fdd5a7e8ad9752ee16e7462.jpg"
class="direct-chat-img big-round">
<span class="direct-chat-reply-name">Singh</span>
</div>
<!-- /.direct-chat-text -->
</div>
<!-- /.direct-chat-msg -->
</div>
</div>
<div class="popup-messages-footer">
<textarea id="status_message" placeholder="Type a message..." rows="10" cols="40" name="message"
ng-model="chatMessage" enter-press="postMessage()"></textarea>
</div>
</div>

View File

@@ -0,0 +1,328 @@
.popup-box {
background-color: #ffffff;
border: 1px solid #b0b0b0;
bottom: 0;
display: none;
height: 415px;
position: fixed;
right: 70px;
width: 300px;
font-family: 'Open Sans', sans-serif;
}
.round.hollow {
margin: 40px 0 0;
}
.round.hollow a {
border: 2px solid #ff6701;
border-radius: 35px;
color: red;
color: #ff6701;
font-size: 23px;
padding: 10px 21px;
text-decoration: none;
font-family: 'Open Sans', sans-serif;
}
.round.hollow a:hover {
border: 2px solid #000;
border-radius: 35px;
color: red;
color: #000;
font-size: 23px;
padding: 10px 21px;
text-decoration: none;
}
.popup-box-on {
display: block !important;
}
.popup-box .popup-head {
background-color: #fff;
clear: both;
color: #7b7b7b;
display: inline-table;
font-size: 21px;
padding: 7px 10px;
width: 100%;
font-family: Oswald;
}
.bg_none i {
border: 1px solid #ff6701;
border-radius: 25px;
color: #ff6701;
font-size: 17px;
height: 33px;
line-height: 30px;
width: 33px;
}
.bg_none:hover i {
border: 1px solid #000;
border-radius: 25px;
color: #000;
font-size: 17px;
height: 33px;
line-height: 30px;
width: 33px;
}
.bg_none {
background: rgba(0, 0, 0, 0) none repeat scroll 0 0;
border: medium none;
}
.popup-box .popup-head .popup-head-right {
margin: 11px 7px 0;
}
.popup-box .popup-messages {
}
.popup-head-left img {
border: 1px solid #7b7b7b;
border-radius: 50%;
width: 44px;
}
.popup-messages-footer > textarea {
border-bottom: 1px solid #b2b2b2 !important;
height: 34px !important;
margin: 7px;
padding: 5px !important;
border: medium none;
width: 95% !important;
}
.popup-messages-footer {
background: #fff none repeat scroll 0 0;
bottom: 0;
position: absolute;
width: 100%;
}
.popup-messages-footer .btn-footer {
overflow: hidden;
padding: 2px 5px 10px 6px;
width: 100%;
}
.simple_round {
background: #d1d1d1 none repeat scroll 0 0;
border-radius: 50%;
color: #4b4b4b !important;
height: 21px;
padding: 0 0 0 1px;
width: 21px;
}
.popup-box .popup-messages {
background: #3f9684 none repeat scroll 0 0;
height: 275px;
overflow: auto;
}
.direct-chat-messages {
overflow: auto;
padding: 10px;
transform: translate(0px, 0px);
}
.popup-messages .chat-box-single-line {
border-bottom: 1px solid #a4c6b5;
height: 12px;
margin: 7px 0 20px;
position: relative;
text-align: center;
}
.popup-messages abbr.timestamp {
background: #3f9684 none repeat scroll 0 0;
color: #fff;
padding: 0 11px;
}
.popup-head-right .btn-group {
display: inline-flex;
margin: 0 8px 0 0;
vertical-align: top !important;
}
.chat-header-button {
background: transparent none repeat scroll 0 0;
border: 1px solid #636364;
border-radius: 50%;
font-size: 14px;
height: 30px;
width: 30px;
}
.popup-head-right .btn-group .dropdown-menu {
border: medium none;
min-width: 122px;
padding: 0;
}
.popup-head-right .btn-group .dropdown-menu li a {
font-size: 12px;
padding: 3px 10px;
color: #303030;
}
.popup-messages abbr.timestamp {
background: #3f9684 none repeat scroll 0 0;
color: #fff;
padding: 0 11px;
}
.popup-messages .chat-box-single-line {
border-bottom: 1px solid #a4c6b5;
height: 12px;
margin: 7px 0 20px;
position: relative;
text-align: center;
}
.popup-messages .direct-chat-messages {
height: auto;
}
.popup-messages .direct-chat-text {
background: #dfece7 none repeat scroll 0 0;
border: 1px solid #dfece7;
border-radius: 2px;
color: #1f2121;
}
.popup-messages .direct-chat-timestamp {
color: #fff;
opacity: 0.6;
}
.popup-messages .direct-chat-name {
font-size: 15px;
font-weight: 600;
margin: 0 0 0 49px !important;
color: #fff;
opacity: 0.9;
}
.popup-messages .direct-chat-info {
display: block;
font-size: 12px;
margin-bottom: 0;
}
.popup-messages .big-round {
margin: -9px 0 0 !important;
}
.popup-messages .direct-chat-img {
border: 1px solid #fff;
background: #3f9684 none repeat scroll 0 0;
border-radius: 50%;
float: left;
height: 40px;
margin: -21px 0 0;
width: 40px;
}
.direct-chat-reply-name {
color: #fff;
font-size: 15px;
margin: 0 0 0 10px;
opacity: 0.9;
}
.direct-chat-img-reply-small {
border: 1px solid #fff;
border-radius: 50%;
float: left;
height: 20px;
margin: 0 8px;
width: 20px;
background: #3f9684;
}
.popup-messages .direct-chat-msg {
margin-bottom: 10px;
position: relative;
}
.popup-messages .doted-border::after {
background: transparent none repeat scroll 0 0 !important;
border-right: 2px dotted #fff !important;
bottom: 0;
content: "";
left: 17px;
margin: 0;
position: absolute;
top: 0;
width: 2px;
display: inline;
z-index: -2;
}
.popup-messages .direct-chat-msg::after {
background: #fff none repeat scroll 0 0;
border-right: medium none;
bottom: 0;
content: "";
left: 17px;
margin: 0;
position: absolute;
top: 0;
width: 2px;
display: inline;
z-index: -2;
}
.direct-chat-text::after, .direct-chat-text::before {
border-color: transparent #dfece7 transparent transparent;
}
.direct-chat-text::after, .direct-chat-text::before {
-moz-border-bottom-colors: none;
-moz-border-left-colors: none;
-moz-border-right-colors: none;
-moz-border-top-colors: none;
border-color: transparent #d2d6de transparent transparent;
border-image: none;
border-style: solid;
border-width: medium;
content: " ";
height: 0;
pointer-events: none;
position: absolute;
right: 100%;
top: 15px;
width: 0;
}
.direct-chat-text::after {
border-width: 5px;
margin-top: -5px;
}
.popup-messages .direct-chat-text {
background: #dfece7 none repeat scroll 0 0;
border: 1px solid #dfece7;
border-radius: 2px;
color: #1f2121;
}
.direct-chat-text {
background: #d2d6de none repeat scroll 0 0;
border: 1px solid #d2d6de;
border-radius: 5px;
color: #444;
margin: 5px 0 0 50px;
padding: 5px 10px;
position: relative;
}

View File

@@ -23,7 +23,7 @@ angular.module('dssWebApp')
$rootScope.$on(CHAT_EVENTS.startChat, function (args, user) {
scope.vm.chattingWith = user;
_loadMessages();
SocketService.registerHandler('user:message', function (message) {
SocketService.on('socket:user:message', function (message) {
console.log("You got a message", message);
if (message.from_user === scope.vm.chattingWith.slug) {
MessageModel.ejectAll({

View File

@@ -3,36 +3,13 @@
angular.module('dssWebApp')
.factory('SocketService', function (socketFactory, Session) {
var ioSocket;
var socket;
return {
socket: socket,
registerHandler: function (message, cb) {
console.log('Registering socket handler for: ' + message);
cb = cb || angular.noop;
if (socket) {
socket.on(message, function (data) {
cb(data);
});
} else {
console.error("Unable to connect to socket service");
}
},
removeHandler: function (event) {
if (socket)
socket.removeAllListeners(event);
},
connectSocket: function (token) {
console.log('Connecting socket: ' + token);
ioSocket = io('', {
query: 'token=' + token,
path: '/socket.io-client'
});
socket = socketFactory({
ioSocket: ioSocket
});
}
};
var ioSocket = io('', {
query: 'token=' + Session.getSession(),
path: '/socket.io-client'
});
var socket = socketFactory({
ioSocket: ioSocket
});
socket.forward('error');
return socket;
});

View File

@@ -0,0 +1,13 @@
angular.module('dssWebApp')
.directive('enterPress', function () {
return function (scope, element, attrs) {
element.bind("keydown keypress", function (event) {
if (event.which === 13) {
scope.$apply(function () {
scope.$eval(attrs.enterPress);
});
event.preventDefault();
}
});
};
});

View File

@@ -11,7 +11,7 @@ angular.module('dssWebApp')
$scope.radioPlaying = false;
$scope.radioLoading = false;
SocketService.registerHandler('site:radio_changed', function (data) {
SocketService.on('socket:site:radio_changed', function (data) {
console.log('site:radio_changed', data);
var d = JSON.parse(data);
$scope.radioNowPlaying = d.message.description;

View File

@@ -38,6 +38,10 @@ angular.module('dssWebApp')
|| false;
};
$scope.$on('socket:error', function (ev, data) {
console.error(data);
});
$scope.isInRole = function (role) {
if ($rootScope.currentUser) {
return Session.isInRole(role);
@@ -96,7 +100,7 @@ angular.module('dssWebApp')
SocketService.removeHandler('site:broadcast');
});
$scope.getMixUrl = function(mix){
$scope.getMixUrl = function (mix) {
var port = window.location.port;
return window.location.protocol +
"//" + window.location.hostname +
@@ -104,7 +108,7 @@ angular.module('dssWebApp')
$state.href('root.user.mix', {user: mix.user.slug, mix: mix.slug});
};
$scope.copyUrl = function(mix){
$scope.copyUrl = function (mix) {
var url = getMixUrl(mix);
console.log("Copied URL", url);
};

View File

@@ -64,6 +64,7 @@ angular.module('dssWebApp')
UserModel.find(data.slug)
.then(function (user) {
Session.create(user);
Session.setSession(data.session);
$rootScope.$broadcast(AUTH_EVENTS.loginSuccess, user);
defer.resolve(user);
}, function (result) {

View File

@@ -48,7 +48,8 @@ angular.module('dssWebApp')
}
function _registerProcessingCallback() {
SocketService.registerHandler('user:process', function (message) {
SocketService.on('user:process', function (message) {
debugger;
console.log("Received user:process message: ", message);
if (message.type === 'waveform' && message.target === _uploadHash) {
$scope.waveformHeader = "Waveform generated.";
@@ -140,7 +141,7 @@ angular.module('dssWebApp')
'<span class="smaller-80 grey">(or click)</span> <br /> <i class="upload-icon ace-icon fa fa-cloud-upload blue fa-3x"></i>',
maxFilesize: 512,
sending: function (file, xhr, formData) {
xhr.setRequestHeader('Session-Id', Session.getSession())
xhr.setRequestHeader('Session-Id', Session.getSession());
xhr.setRequestHeader('Upload-Hash', _uploadHash);
$scope.uploadState = uploadStates.AUDIO_SENDING;
$scope.$apply();
@@ -152,7 +153,7 @@ angular.module('dssWebApp')
},
complete: function (file) {
if (file.status !== 'error') {
$scope.waveformHeader = "Generating waveform.";
$scope.waveformHeader = "Generating waveform, we'll try to let you know when it's done or send you an email.";
$scope.uploadState = uploadStates.AUDIO_SENT;
$scope.$apply();
_checkRedirect();

View File

@@ -2,162 +2,165 @@
<button type="button" ng-click="login()" class="btn btn-sm btn-danger">Login</button>
</div>
<div ng-show="$root.currentUser" class="row">
<div ng-show="uploadState <= uploadStates.AUDIO_SENT" class="text-center row">
<div class="block full">
<form id="dss-file-upload" ng-show="uploadState==0" class="dropzone">
</form>
</div>
</div>
<div ng-show="uploadState != uploadStates.VIRGIN && (!detailsEntered || uploadState == uploadStates.EDIT_MODE)"
class="col-md-8">
<div class="block">
<div class="block-title">
<h2>Mix<strong>Details</strong></h2>
</div>
<form name="uploadForm" ng-submit="saveMix()" class="form-horizontal form-bordered">
<input type="hidden" ng-model="mix.uid"/>
<div id="title-area" show-errors="{ trigger: 'keypress' }" class="form-group"
ng-class="uploadForm.title.$invalid ? 'error' : ''">
<label for="title" class="col-sm-3 control-label">Title</label>
<div class="col-sm-6">
<input type="text" id="title" name="title" required="" ng-minlength="5" ng-maxlength="250"
ng-model="mix.title" class="form-control input-sm"/>
<p for="title" ng-show="uploadForm.title.$invalid &amp;&amp; uploadForm.title.$dirty"
class="help-block">Title must be between 5 and 250 characters</p>
<p for="title"
ng-show="(uploadForm.title.$error.required) &amp;&amp; uploadForm.$dirty &amp;&amp;!(uploadForm.title.$invalid &amp;&amp; uploadForm.title.$dirty)"
class="help-block">Title is a must</p>
class="row">
<div class="block text-center">
<div class="col-md-2"></div>
<div class="col-md-8">
<div class="row">
<div ng-show="uploadState==1" class="progress progress-striped">
<div role="progressbar" aria-valuenow="uploadProgress" aria-valuemin="0" aria-valuemax="100"
ng-style="uploadProgressStyle" class="progress-bar progress-bar-success">
{{uploadProgress}}%
</div>
</div>
</div>
<div id="description-area" show-errors="" class="form-group">
<label for="description" class="col-sm-3 control-label">Description</label>
<div class="row">
<div ng-show="uploadState==2" class="widget widget-simple col-md-8">
<div>
<h6 class="description">
{{waveformHeader}}
</h6>
</div>
</div>
</div>
<div class="row">
<form name="uploadForm" ng-submit="saveMix()" class="form-horizontal">
<input type="hidden" ng-model="mix.uid"/>
<div class="col-sm-6">
<div id="title-area" show-errors="{ trigger: 'keypress' }" class="form-group"
ng-class="uploadForm.title.$invalid ? 'error' : ''">
<label for="title" class="col-sm-3 control-label">Title</label>
<div class="col-sm-6">
<input type="text" id="title" name="title" required="" ng-minlength="5"
ng-maxlength="250"
ng-model="mix.title" class="form-control input-sm"/>
<p for="title" ng-show="uploadForm.title.$invalid &amp;&amp; uploadForm.title.$dirty"
class="help-block">Title must be between 5 and 250 characters</p>
<p for="title"
ng-show="(uploadForm.title.$error.required) &amp;&amp; uploadForm.$dirty &amp;&amp;!(uploadForm.title.$invalid &amp;&amp; uploadForm.title.$dirty)"
class="help-block">Title is a must</p>
</div>
</div>
<div id="description-area" show-errors="" class="form-group">
<label for="description" class="col-sm-3 control-label">Description</label>
<div class="col-sm-6">
<textarea type="text" id="description" name="description" rows="5" required="" ng-minlength="10"
ng-maxlength="2000" ng-model="mix.description" class="form-control"></textarea>
<p for="description"
ng-show="uploadForm.description.$invalid &amp;&amp; uploadForm.description.$dirty"
class="help-block">Description must be between 10 and 2000 characters</p>
<p for="description"
ng-show="uploadForm.description.$invalid &amp;&amp; uploadForm.description.$dirty"
class="help-block">Description must be between 10 and 2000 characters</p>
<p for="description"
ng-show="(uploadForm.description.$error.required) &amp;&amp; uploadForm.$dirty &amp;&amp;!(uploadForm.description.$invalid &amp;&amp; uploadForm.description.$dirty)"
class="help-block">Description is a must</p>
</div>
</div>
<div id="image-area" class="form-group">
<label class="col-sm-3 control-label">Image</label>
<div class="col-sm-3">
<div data-provides="fileinput" class="fileinput fileinput-new">
<div data-trigger="fileinput" style="width: 200px; height: 150px;"
class="fileinput-preview thumbnail">
<img id="mix-image"
ng-src="{{mix.mix_image ? mix.mix_image : &quot;assets/images/image-upload-placeholder.png&quot;}}"
class="editable img-responsive image-user-profile"/>
<p for="description"
ng-show="(uploadForm.description.$error.required) &amp;&amp; uploadForm.$dirty &amp;&amp;!(uploadForm.description.$invalid &amp;&amp; uploadForm.description.$dirty)"
class="help-block">Description is a must</p>
</div>
<div>
</div>
<div id="image-area" class="form-group">
<label class="col-sm-3 control-label">Image</label>
<div class="col-sm-3">
<div data-provides="fileinput" class="fileinput fileinput-new override-text-align">
<div data-trigger="fileinput" style="width: 200px; height: 150px;"
class="fileinput-preview thumbnail override-text-align">
<img id="mix-image"
ng-src="{{mix.mix_image ? mix.mix_image : &quot;assets/images/image-upload-placeholder.png&quot;}}"
class="editable img-responsive image-user-profile"/>
</div>
<div>
<span class="btn btn-default btn-file">
<span class="fileinput-new">Select image</span>
<span class="fileinput-exists">Change</span>
<input id="mix-image-fileinput" type="file" name="..."/>
</span>
<a href="#" data-dismiss="fileinput" class="btn btn-default fileinput-exists">
Remove
</a>
<a href="#" data-dismiss="fileinput" class="btn btn-default fileinput-exists">
Remove
</a>
</div>
</div>
</div>
<div class="col-sm-3">
<table class="table table-striped table-vcenter">
<tbody>
<tr>
<td>
Private
</td>
<td>
<div class="checkbox">
<label class="switch switch-primary">
<input ng-model="mix.is_private" type="checkbox" checked="">
<span></span>
</label>
</div>
</td>
</tr>
<tr>
<td>
Downloadable
</td>
<td>
<div class="checkbox">
<label class="switch switch-primary">
<input ng-model="mix.is_downloadable" type="checkbox" checked="">
<span></span>
</label>
</div>
</td>
</tr>
<tr>
<td>
Homepage
</td>
<td>
<div class="checkbox">
<label class="switch switch-primary">
<input ng-model="mix.is_featured" type="checkbox" checked="">
<span></span>
</label>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-sm-4">
<table class="table table-striped table-vcenter">
<tbody>
<tr>
<td>
Private
</td>
<td>
<div class="checkbox">
<label class="switch switch-primary">
<input ng-model="mix.is_private" type="checkbox" checked="">
<span></span>
</label>
</div>
</td>
</tr>
<tr>
<td>
Downloadable
</td>
<td>
<div class="checkbox">
<label class="switch switch-primary">
<input ng-model="mix.is_downloadable" type="checkbox" checked="">
<span></span>
</label>
</div>
</td>
</tr>
<tr>
<td>
Homepage
</td>
<td>
<div class="checkbox">
<label class="switch switch-primary">
<input ng-model="mix.is_featured" type="checkbox" checked="">
<span></span>
</label>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="genres-area" class="form-group">
<label class="col-sm-3 control-label">Genres</label>
<div class="col-sm-6">
<ui-select multiple ng-model="mix.genres" theme="bootstrap" ng-disabled="disabled"
style="width: 300px;">
<ui-select-match placeholder="Start typing...">{{$item.description}}</ui-select-match>
<ui-select-choices repeat="genre in genreSearchResults"
refresh="refreshGenres($select.search)"
refresh-delay="0">
<div ng-bind-html="genre.description | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
</div>
</div>
<div id="submit-area" class="form-group form-actions">
<div class="col-sm-9 col-sm-offset-3">
<button formnovalidate="" type="submit" class="btn btn-sm btn-primary"
ng-disabled="sending">
<i class="fa fa-save"></i> Save
</button>
</div>
</div>
</form>
</div>
</div>
<div ng-show="uploadState <= uploadStates.AUDIO_SENT" class="col-md-4">
<div class="block full">
<div class="block-title">
<h2><strong>Audio file</strong>
<small>{{waveformHeader}}</small>
</h2>
</div>
<div ng-show="uploadState==2" class="widget widget-simple">
<div>
<img src="/assets/images/waveform-interstitial.gif" style="width: 100%; height: 132px;">
<div>
<p ng-bind-html="waveformFooter | unsafe"></p>
</div>
<div id="genres-area" class="form-group">
<label class="col-sm-3 control-label">Genres</label>
<div class="col-sm-6">
<ui-select multiple ng-model="mix.genres" theme="bootstrap" ng-disabled="disabled">
<ui-select-match placeholder="Start typing...">{{$item.description}}
</ui-select-match>
<ui-select-choices repeat="genre in genreSearchResults"
refresh="refreshGenres($select.search)"
refresh-delay="0">
<div ng-bind-html="genre.description | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
</div>
</div>
<div id="submit-area" class="form-group form-actions">
<div class="col-sm-12">
<button formnovalidate="" type="submit" class="btn btn-lg btn-primary"
ng-disabled="sending" style="width: 100%;">
<i class="fa fa-save"></i> Save
</button>
</div>
</div>
</form>
</div>
</div>
<div ng-show="uploadState==1" class="progress progress-striped">
<div role="progressbar" aria-valuenow="uploadProgress" aria-valuemin="0" aria-valuemax="100"
ng-style="uploadProgressStyle" class="progress-bar progress-bar-success">{{uploadProgress}}%
</div>
</div>
<form id="dss-file-upload" ng-show="uploadState==0" class="dropzone"></form>
<div class="col-md-2"></div>
</div>
</div>
</div>

View File

@@ -25,6 +25,7 @@
<link rel="stylesheet" href="bower_components/fullcalendar/dist/fullcalendar.css" />
<link rel="stylesheet" href="bower_components/smalot-bootstrap-datetimepicker/css/bootstrap-datetimepicker.min.css" />
<link rel="stylesheet" href="bower_components/ui-select/dist/select.css" />
<link rel="stylesheet" href="bower_components/angular-toastr/dist/angular-toastr.css" />
<!-- endbower -->
<!-- endbuild -->
@@ -56,13 +57,13 @@
</div>
</div>
</div>
<!--<div ui-view="chatbar"></div>-->
<div id="footer" ng-show="isPlaying" ui-view="footer" class="app-footer"
style="position: fixed; bottom: 0px; top: auto;">
</div>
<div id="spoon-plugin-kncgbdglledmjmpnikebkagnchfdehbm-2" style="display:none"></div>
</body>
<script src="//connect.facebook.net/en_US/sdk.js"></script>
<script src="bower_components/socket.io-client/socket.io.js"></script>
<!--[if lt IE 9]>
<script src="bower_components/es5-shim/es5-shim.js"></script>
<script src="bower_components/json3/lib/json3.min.js"></script>
@@ -86,7 +87,6 @@
<script src="bower_components/angular-mocks/angular-mocks.js"></script>
<script src="bower_components/angular-resource/angular-resource.js"></script>
<script src="bower_components/angular-smilies/dist/angular-smilies.js"></script>
<script src="bower_components/angular-socket-io/socket.js"></script>
<script src="bower_components/angular-ui-router/release/angular-ui-router.js"></script>
<script src="bower_components/waypoints/waypoints.js"></script>
<script src="bower_components/SHA-1/sha1.js"></script>
@@ -126,8 +126,9 @@
<script src="bower_components/ng-clip/src/ngClip.js"></script>
<script src="bower_components/satellizer/satellizer.js"></script>
<script src="bower_components/ngInfiniteScroll/build/ng-infinite-scroll.js"></script>
<script src="bower_components/angular-socket-io/socket.js"></script>
<script src="bower_components/angular-toastr/dist/angular-toastr.tpls.js"></script>
<!-- endbower -->
<script src="socket.io-client/socket.io.js"></script>
<!-- endbuild -->
<!-- build:js({.tmp,client}) app/app.js -->
@@ -166,6 +167,7 @@
<script src="app/directives/audio/audio.player.directive.js"></script>
<script src="app/directives/misc/checkboxBitfield.js"></script>
<script src="app/directives/misc/ckeditor.js"></script>
<script src="app/directives/misc/enterpress.js"></script>
<script src="app/directives/misc/focus.js"></script>
<script src="app/directives/misc/timeAgo.js"></script>
<script src="app/directives/misc/tooltip.js"></script>

View File

@@ -8,6 +8,6 @@ module.exports = {
seedDB: true,
redisHost: 'localhost',
apiUrl: 'https://ext-test.deepsouthsounds.com:8001',
apiUrl: 'http://ext-test.deepsouthsounds.com:8001',
radioUrl: 'http://localhost:8000'
};