Moving to Angular Material, removed jQuery UI

This commit is contained in:
Josef Citrine 2016-08-03 01:37:23 +01:00
parent 307449a02d
commit 1fb70bbfa5
22 changed files with 300 additions and 15496 deletions

View file

@ -97,8 +97,6 @@ class Assets
{
if ($area == 'app') {
return [
"styles/base/jquery-ui.css",
"styles/base/colorbox.css",
"styles/app.less",
];
} else {

View file

@ -7,17 +7,18 @@
"url": "ssh://git@phabricator.poniverse.net/diffusion/PF/pony-fm.git"
},
"packages": {},
"dependencies": {
"color-thief": "github:logic-dev/color-thief"
},
"devDependencies": {
"angular": "1.5.6",
"angular-animate": "^1.5.8",
"angular-aria": "^1.5.8",
"angular-chart.js": "1.0.0-alpha6",
"angular-material": "^1.1.0-rc.5",
"angular-strap": "2.3.8",
"angular-ui-router": "0.2.18",
"chart.js": "2.1.0",
"coffee-loader": "0.7.2",
"coffee-script": "1.10.0",
"color-thief": "github:logic-dev/color-thief",
"gulp": "3.9.1",
"gulp-angular-templatecache": "1.8.0",
"gulp-autoprefixer": "3.1.0",

View file

@ -1,19 +1,9 @@
<ul class="tabs">
<li ui-sref-active="active">
<a ui-sref=".uploader">Upload music!</a>
</li>
<li ui-sref-active="active">
<a ui-sref=".tracks">Tracks</a>
</li>
<li ui-sref-active="active">
<a ui-sref=".albums">Albums</a>
</li>
<li ui-sref-active="active">
<a ui-sref=".playlists">Playlists</a>
</li>
<li ui-sref-active="active">
<a ui-sref=".settings">Settings</a>
</li>
</ul>
<md-tabs class="account-tabs manage-account-tabs" md-selected="currentNavItem" md-border-bottom>
<md-tab ui-sref=".uploader" name="uploader">Upload music</md-tab>
<md-tab ui-sref=".tracks" name="tracks">Tracks</md-tab>
<md-tab ui-sref=".albums" name="albums">Albums</md-tab>
<md-tab ui-sref=".playlists" name="playlists">Playlists</md-tab>
<md-tab ui-sref=".settings" name="settings">Settings</md-tab>
</md-tabs>
<ui-view></ui-view>

View file

@ -18,14 +18,12 @@
</div>
</header>
<ul class="tabs header">
<li ui-sref-active="active"><a ui-sref=".profile">Profile</a></li>
<li ui-sref-active="active"><a ui-sref=".content">Content</a></li>
<li ng-if="::!artist.is_archived" ui-sref-active="active">
<a ui-sref=".favourites">Favourites</a>
</li>
<li ng-if="::artist.permissions.edit" ui-sref-active="{active: '.account'}"><a ui-sref=".account.settings">Manage Account</a></li>
</ul>
<md-tabs class="account-tabs" md-selected="selectedTab" md-border-bottom>
<md-tab ui-sref=".profile" name="profile">Profile</md-tab>
<md-tab ui-sref=".content" name="content">Content</md-tab>
<md-tab ng-if="::!artist.is_archived" ui-sref=".favourites" name="favourites">Favourites</md-tab>
<md-tab ng-if="::artist.permissions.edit" ui-sref=".account.settings" name="settings">Manage Account</md-tab>
</md-tabs>
<div class="stretch-to-bottom secondary-content">
<ui-view></ui-view>
</div>

View file

@ -1,4 +1,4 @@
<ul class="albums-listing {{::class}}">
<div><!--<ul class="albums-listing {{::class}}">
<li ng-repeat="album in albums track by album.id">
<a ng-href="{{::album.url}}">
<img class="image" pfm-src-loader="::album.covers.normal" pfm-src-size="normal" />
@ -18,4 +18,23 @@
<li ng-if="!albums.length" class="empty">
No albums found&hellip;
</li>
</ul>
</ul>-->
<div flex-xs="50" flex-gt-xs="25" layout="column">
<a ng-repeat="album in albums track by album.id" ng-href="{{::album.url}}" class="clickable">
<md-card class="album">
<img class="md-card-image" pfm-src-loader="::album.covers.normal" pfm-src-size="normal">
<md-card-content>
<span>{{::album.title}}</span>
</md-card-content>
<md-card-actions layout="row" layout-align="end center" class="album-stats">
<span><md-icon>favorite</md-icon> {{::album.stats.favourites}}</span>
<span><md-icon>comment</md-icon> {{::album.stats.comments}}</span>
<span><md-icon>file_download</md-icon> {{::album.stats.downloads}}</span>
</md-card-actions>
</md-card>
</a>
</div>
</div>

View file

@ -1,135 +1,127 @@
<form class="track-editor" novalidate ng-submit="updateTrack(track)">
<ul class="toolbar">
<li>
<button type="submit" class="btn btn-default" ng-class="{disabled: (track.is_published && !isDirty) || isSaving, 'btn-primary': !track.is_published || isDirty}">
<span ng-show="track.is_published">
Save Changes
</span>
<span ng-hide="track.is_published">
Publish Track
</span>
<i ng-show="isSaving" class="fa fa-cog fa-spin fa-lg"></i>
</button>
</li>
<li class="delete"><a ng-class="{disabled: isSaving}" class="btn btn-danger" href="#" ng-click="deleteTrack()" pfm-eat-click>Delete Track</a></li>
</ul>
<div class="stretch-to-bottom">
<div class="row">
<div class="col-sm-12 form-row" ng-class="{'has-error': errors.title != null}">
<label for="title" class="strong">Title:</label>
<input ng-disabled="isSaving" ng-change="touchModel()" placeholder="Track Title" type="text" id="title" ng-model="track.title" />
<div class="error">{{errors.title}}</div>
</div>
<div layout="row">
<md-button class="md-raised md-primary" type="submit" ng-class="{disabled: (track.is_published && !isDirty) || isSaving, 'btn-primary': !track.is_published || isDirty}" flex>
<span ng-show="track.is_published">
Save Changes
</span>
<span ng-hide="track.is_published">
Publish Track
</span>
<i ng-show="isSaving" class="fa fa-cog fa-spin fa-lg"></i>
</md-button>
<div flex="5" hide-xs hide-sm>
<!-- Spacer //-->
</div>
<div class="row">
<div class="col-sm-6 form-row" ng-class="{'has-error': errors.description != null}">
<label for="description" class="strong">Description:</label>
<textarea ng-disabled="isSaving" ng-change="touchModel()" placeholder="Description (optional)" id="description" ng-model="track.description"></textarea>
<div class="error">{{errors.description}}</div>
</div>
<div class="col-sm-6 form-row" ng-class="{'has-error': errors.lyrics != null}">
<label for="is_vocal" class="strong"><input ng-disabled="isSaving" ng-change="touchModel(); updateIsVocal()" id="is_vocal" type="checkbox" ng-model="track.is_vocal" /> Is Vocal</label>
<textarea ng-disabled="isSaving" ng-change="touchModel()" ng-show="track.is_vocal" ng-animate="'fade'" placeholder="Lyrics (optional)" id="lyrics" ng-model="track.lyrics"></textarea>
<div class="error">{{errors.lyrics}}</div>
</div>
<md-button ng-class="{disabled: isSaving}" class="md-raised md-warn" href="#" ng-click="deleteTrack()" pfm-eat-click flex>Delete Track</md-button>
</div>
<div layout-gt-xs="row" ng-class="{'has-error': errors.title != null}">
<md-input-container class="md-block" flex-gt-xs id="title">
<label for="title">Title</label>
<input ng-disabled="isSaving" type="text" id="title" ng-model="track.title" />
</md-input-container>
</div>
<div layout="row" layout-xs="column" ng-class="{'has-error': errors.description != null}">
<md-input-container class="md-block" flex-gt-sm>
<label for="description">Description</label>
<textarea ng-disabled="isSaving" id="description" ng-model="track.description" rows="3"></textarea>
</md-input-container>
<div flex="5" hide-xs hide-sm>
<!-- Spacer //-->
</div>
<div class="row">
<div class="form-row col-sm-6" ng-class="{'has-error': errors.genre_id != null}">
<label for="genre" class="strong">Genre:</label>
<select ng-disabled="isSaving" id="genre" ng-change="touchModel()" ng-model="track.genre_id" ng-options="genre.id as genre.name for genre in taxonomies.genres">
<option value="">Please select a genre...</option>
</select>
<div class="error">{{errors.genre_id}}</div>
</div>
<div class="form-row col-sm-6" ng-class="{'has-error': errors.track_type_id != null}">
<label for="track_type" class="strong">This track is...</label>
<select ng-disabled="isSaving" id="track_type" ng-change="touchModel()" ng-model="track.track_type_id" ng-options="type.id as type.editor_title for type in taxonomies.trackTypes">
<option value="">Please select a type...</option>
</select>
<div class="error">{{errors.track_type_id}}</div>
</div>
<md-input-container class="md-block" flex-gt-sm>
<label for="lyrics">Lyrics (requires 'has vocals')</label>
<textarea ng-disabled="isSaving || !track.is_vocal" id="lyrics" ng-model="track.lyrics" rows="3"></textarea>
</md-input-container>
</div>
<div layout="row" layout-xs="column">
<md-input-container flex-gt-sm>
<label>Genre</label>
<md-select ng-disabled="isSaving" id="genre" ng-model="track.genre_id">
<md-option ng-repeat="genre in taxonomies.genres" value="{{genre.id}}">{{genre.name}}</md-option>
</md-select>
</md-input-container>
<md-input-container flex-gt-sm>
<label for="track_type" class="strong">This track is...</label>
<md-select ng-disabled="isSaving" id="track_type" ng-model="track.track_type_id">
<md-option ng-repeat="type in taxonomies.trackTypes" value="{{type.id}}">{{type.editor_title}}</md-option>
</md-select>
</md-input-container>
<div flex="5" hide-xs hide-sm>
<!-- Spacer //-->
</div>
<div class="row">
<div class="form-row album-selector col-sm-6" ng-class="{'has-error': errors.album_id != null}">
<a pfm-popup="album-selector" pfm-popup-close-on-click href="#" class="btn btn-default">
Album:
<strong ng-show="selectedAlbum">{{selectedAlbum.title}}</strong>
<strong ng-hide="selectedAlbum">None</strong>
</a>
<div id="album-selector" class="pfm-popup">
<ul>
<li ng-class="{selected: selectedAlbum == null}">
<a pfm-eat-click href="#" ng-click="selectAlbum(null);">None</a>
</li>
<li ng-repeat="album in albums track by album.id" ng-class="{selected: selectedAlbum.id == album.id}">
<a pfm-eat-click href="#" ng-click="selectAlbum(album);">{{::album.title}}</a>
</li>
</ul>
</div>
<div class="error">{{errors.album_id}}</div>
</div>
<div class="form-row show-songs-selector col-sm-6" ng-show="track.track_type_id == 2" ng-class="{'has-error': errors.show_song_ids != null}">
<a pfm-popup="song-selector" pfm-popup-close-on-click href="#" class="btn btn-default">Show Songs: <strong>{{selectedSongsTitle}}</strong></a>
<div id="song-selector" class="pfm-popup">
<ul>
<li ng-repeat="song in taxonomies.showSongs track by song.id" ng-class="{selected: selectedSongs[song.id]}">
<a pfm-eat-click href="#" ng-click="toggleSong(song); $event.stopPropagation();">{{::song.title}}</a>
</li>
</ul>
</div>
<div class="error">{{errors.show_song_ids}}</div>
</div>
<md-datepicker ng-disabled="isSaving" ng-model="track.released_at" md-placeholder="Release date" flex-gt-sm></md-datepicker>
</div>
<div layout="row" layout-xs="column">
<md-input-container flex-gt-sm>
<label>Album</label>
<md-select ng-disabled="isSaving" ng-model="selectedAlbum">
<md-option ng-repeat="album in albums track by album.title" value="{{album.id}}">{{album.title}}</md-option>
</md-select>
</md-input-container>
<md-input-container flex-gt-sm>
<label>Show songs</label>
<md-select ng-disabled="isSaving || track.track_type_id != 2" ng-model="selectedSongs">
<md-option ng-repeat="song in taxonomies.showSongs track by song.title" value="{{song.id}}">{{song.title}}</md-option>
</md-select>
</md-input-container>
</div>
<div layout="row" layout-xs="column">
<div flex>
<label class="strong">Track Cover: </label>
<pfm-image-upload set-image="setCover" image="track.cover_url" user-id="track.user_id"></pfm-image-upload>
</div>
<div class="row">
<div class="form-row col-sm-6" ng-class="{'has-error': errors.cover != null}">
<label class="strong">Track Cover: </label>
<pfm-image-upload set-image="setCover" image="track.cover_url" user-id="track.user_id"></pfm-image-upload>
</div>
<div class="form-row col-sm-6" ng-class="{'has-error': errors.released_at != null}">
<label for="released_at" class="strong">Release Date:</label>
<input
id="released_at"
type="text"
ui-date
ng-disabled="isSaving"
ng-model="track.released_at"
ng-change="touchModel()"
/>
<div class="error">{{errors.released_at}}</div>
</div>
</div>
<div class="row">
<div class="col-md-4 form-row">
<label for="is_explicit"><input ng-disabled="isSaving" ng-change="touchModel()" id="is_explicit" type="checkbox" ng-model="track.is_explicit" /> Contains Explicit Content</label>
</div>
<div class="col-md-4 form-row">
<label for="is_downloadable"><input ng-disabled="isSaving" ng-change="touchModel()" id="is_downloadable" type="checkbox" ng-model="track.is_downloadable" /> Is Downloadable</label>
</div>
<div class="col-md-4 form-row">
<label for="is_listed"><input ng-disabled="isSaving" ng-change="touchModel()" id="is_listed" type="checkbox" ng-model="track.is_listed" /> Is Listed</label>
</div>
</div>
<div class="row" ng-show="isAdmin">
<div class="col-sm-6 form-row" ng-class="{'has-error': errors.username != null}">
<label for="title" class="strong">User:</label>
<input ng-disabled="isSaving" ng-change="touchModel()" placeholder="Username" type="text" id="username" ng-model="track.username" />
<div class="error">{{errors.username}}</div>
</div>
</div>
<div class="form-row">
<label class="strong">Choose a License:</label>
<ul class="license-grid">
<li ng-repeat="license in taxonomies.licenses track by license.id" ng-class="{selected: track.license_id == license.id}">
<div ng-click="track.license_id = license.id; touchModel()">
<strong>{{::license.title}}</strong>
<p>{{::license.description}}</p>
<a href="#" pfm-eat-click class="btn btn-default" ng-class="{'btn-primary': track.license_id == license.id, 'disabled': isSaving}">
<span ng-hide="track.license_id == license.id">Select</span>
<span ng-show="track.license_id == license.id">Selected</span>
</a>
</div>
</li>
</ul>
<div class="form-row col-sm-6" ng-class="{'has-error': errors.released_at != null}">
</div>
</div>
<div layout="row" layout-xs="column" class="checkboxes">
<md-input-container flex-gt-sm>
<md-checkbox ng-disabled="isSaving" ng-model="track.is_explicit">Contains Explicit Content</md-checkbox>
</md-input-container>
<md-input-container flex-gt-sm>
<md-checkbox ng-disabled="isSaving" ng-model="track.is_downloadable">Allow Downloads</md-checkbox>
</md-input-container>
<md-input-container flex-gt-sm>
<md-checkbox ng-disabled="isSaving" ng-model="track.is_listed">Is Public</md-checkbox>
</md-input-container>
<md-input-container flex-gt-sm>
<md-checkbox ng-disabled="isSaving" id="is_vocal" ng-model="track.is_vocal">Has Vocals</md-checkbox>
</md-input-container>
</div>
<div class="row" ng-show="isAdmin">
<div class="col-sm-6 form-row" ng-class="{'has-error': errors.username != null}">
<label for="title" class="strong">User:</label>
<input ng-disabled="isSaving" ng-change="touchModel()" placeholder="Username" type="text" id="username" ng-model="track.username" />
<div class="error">{{errors.username}}</div>
</div>
</div>
<div class="form-row">
<label class="strong">Choose a License:</label>
<ul class="license-grid">
<li ng-repeat="license in taxonomies.licenses track by license.id" ng-class="{selected: track.license_id == license.id}">
<div ng-click="track.license_id = license.id; touchModel()">
<strong>{{::license.title}}</strong>
<p>{{::license.description}}</p>
<a href="#" pfm-eat-click class="btn btn-default" ng-class="{'btn-primary': track.license_id == license.id, 'disabled': isSaving}">
<span ng-hide="track.license_id == license.id">Select</span>
<span ng-show="track.license_id == license.id">Selected</span>
</a>
</div>
</li>
</ul>
</div>
</form>

View file

@ -4,18 +4,6 @@
<img class="cover" pfm-src-loader="track.covers.normal" pfm-src-size="normal"/>
</a>
<div class="share-buttons" pfm-share-buttons>
<a class="tumblr" ng-href="{{::track.share.tumblrUrl}}"
title="Share on Tumblr"
style="display:inline-block; overflow:hidden; width:20px; height:20px; background:url('/images/tumblr-share.png') top left no-repeat transparent;"></a>
<div class="facebook fb-like" data-href="{{::track.url}}"
data-width="450" data-layout="button_count"
data-show-faces="true" data-send="false"></div>
<iframe class="twitter" allowtransparency="true" frameborder="0"
scrolling="no" ng-src="{{::track.share.twitterUrl}}"
style="width:130px; height:20px;"></iframe>
</div>
<ul class="stats">
<li>Published: <strong>{{::track.published_at}}</strong></li>
<li>Views: <strong>{{::track.stats.views}}</strong></li>

View file

@ -27,21 +27,18 @@
# and other Angular modules are brought in; they expect the "ponyfm" module to exist.
require 'script!../base/jquery-2.0.2'
require 'script!../base/jquery-ui'
angular = require 'angular'
require 'script!../base/angular-ui-date'
require 'angular-ui-router'
require 'angular-material'
require '../base/angular-ui-sortable'
require '../base/angularytics'
require '../base/jquery.colorbox'
require '../base/jquery.cookie'
require '../base/jquery.timeago'
require '../base/jquery.viewport'
require 'script!../base/marked'
require 'script!../base/moment'
require '../base/soundmanager2-nodebug'
require 'script!../base/tumblr'
require 'color-thief';
require 'angular-strap'
# Just ignore this, blame webpack
@ -54,7 +51,7 @@ require '../shared/pfm-angular-sanitize'
require '../shared/init.coffee'
ponyfm = angular.module 'ponyfm', ['mgcrea.ngStrap', 'ui.router', 'ui.date', 'ui.sortable', 'angularytics', 'ngSanitize', 'hc.marked', 'chart.js']
ponyfm = angular.module 'ponyfm', ['ngMaterial', 'mgcrea.ngStrap', 'ui.router', 'ui.sortable', 'angularytics', 'ngSanitize', 'hc.marked', 'chart.js']
window.pfm.preloaders = {}
# Inspired by: https://stackoverflow.com/a/30652110/3225811
@ -82,8 +79,8 @@ ponyfm.run [
]
ponyfm.config [
'$locationProvider', '$stateProvider', 'AngularyticsProvider', '$httpProvider', '$sceDelegateProvider', 'markedProvider'
(location, state, analytics, $httpProvider, $sceDelegateProvider, markedProvider) ->
'$locationProvider', '$stateProvider', 'AngularyticsProvider', '$httpProvider', '$sceDelegateProvider', 'markedProvider', '$mdDateLocaleProvider', '$mdThemingProvider'
(location, state, analytics, $httpProvider, $sceDelegateProvider, markedProvider, $mdDateLocaleProvider, $mdThemingProvider) ->
if window.pfm.environment == 'local'
$httpProvider.interceptors.push [
@ -128,6 +125,37 @@ ponyfm.config [
del: (text) ->
text
$mdDateLocaleProvider.formatDate = (date) ->
return moment(date).format('DD/MM/YYYY')
$mdDateLocaleProvider.parseDate = (string) ->
return moment(date).format('DD/MM/YYYY')
pfmPurple = $mdThemingProvider.extendPalette('purple', {
'50': '#f5eff6',
'100': '#d6bfd9',
'200': '#c09cc4',
'300': '#a36faa',
'400': '#965d9d',
'500': '#84528a',
'600': '#724777',
'700': '#5f3b64',
'800': '#4d3050',
'900': '#3b243d',
'A100': '#c09cc4',
'A200': '#965d9d',
'A400': '#724777',
'A700': '#65326b',
'contrastDefaultColor': 'light',
'contrastDarkColors': '50 100 200 300 A100'
})
$mdThemingProvider.definePalette('pfmPurple', pfmPurple)
$mdThemingProvider.theme('default')
.primaryPalette('pfmPurple')
.accentPalette('pfmPurple')
.warnPalette('red')
# Errors
state.state 'errors-404',

View file

@ -23,6 +23,8 @@ window.pfm.preloaders['artist'] = [
module.exports = angular.module('ponyfm').controller "artist", [
'$scope', 'artists', '$state', 'follow', '$rootScope', 'color'
($scope, artists, $state, follow, $rootScope, color) ->
$scope.selectedTab = 0
updateArtist = (force = false) ->
if force
window.location.reload()
@ -45,12 +47,23 @@ module.exports = angular.module('ponyfm').controller "artist", [
$('.top-bar').css('background': color.selectHeaderColour(palette[0], palette[1]))
$scope.$apply()
evaluateTab = (route) ->
switch route
when 'content.artist.profile' then $scope.selectedTab = 0
when 'content.artist.content' then $scope.selectedTab = 1
when 'content.artist.favourites' then $scope.selectedTab = 2
when 'content.artist.account.settings' then $scope.selectedTab = 3
$scope.toggleFollow = () ->
follow.toggle('artist', $scope.artist.id).then (res) ->
$scope.artist.user_data.is_following = res.is_followed
updateArtist()
evaluateTab($state.current.name)
$scope.$on 'user-updated', ->
updateArtist(true)
$rootScope.$on '$stateChangeStart', (e, to, toParam, from, fromParam) ->
evaluateTab to.name
]

View file

@ -33,11 +33,6 @@ module.exports = angular.module('ponyfm').directive 'pfmTrackEditor', () ->
$scope.isAdmin = auth.data.isAdmin
albumsDb = {}
$scope.selectAlbum = (album) ->
$scope.selectedAlbum = album
$scope.track.album_id = if album then album.id else null
$scope.isDirty = true
$scope.setCover = (image, type) ->
delete $scope.track.cover_id
delete $scope.track.cover
@ -108,7 +103,7 @@ module.exports = angular.module('ponyfm').directive 'pfmTrackEditor', () ->
formData.append name, value
if parseInt($scope.track.track_type_id) == 2
formData.append 'show_song_ids', _.map(_.values($scope.selectedSongs), (s) -> s.id).join()
formData.append 'show_song_ids', $scope.selectedSongs
xhr.open 'POST', '/api/web/tracks/edit/' + $scope.track.id, true
xhr.setRequestHeader 'X-XSRF-TOKEN', $.cookie('XSRF-TOKEN')
@ -139,7 +134,7 @@ module.exports = angular.module('ponyfm').directive 'pfmTrackEditor', () ->
for album in albums
albumsDb[album.id] = album
$scope.albums.push album
$scope.selectedAlbum = if track.album_id then albumsDb[track.album_id] else null
$scope.selectedAlbum = track.album_id
# Update track data

View file

@ -1,283 +0,0 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("jquery"), require("angular"), require("jquery-ui/datepicker"));
else if(typeof define === 'function' && define.amd)
define(["jquery", "angular", "jquery-ui/datepicker"], factory);
else if(typeof exports === 'object')
exports["angularUiDate"] = factory(require("jquery"), require("angular"), require("jquery-ui/datepicker"));
else
root["angularUiDate"] = factory(root["jQuery"], root["angular"], root["jquery-ui/datepicker"]);
})(this, function(__WEBPACK_EXTERNAL_MODULE_1__, __WEBPACK_EXTERNAL_MODULE_2__, __WEBPACK_EXTERNAL_MODULE_3__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "assets";
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _jquery = __webpack_require__(1);
var _jquery2 = _interopRequireDefault(_jquery);
var _angular = __webpack_require__(2);
var _angular2 = _interopRequireDefault(_angular);
var _datepicker = __webpack_require__(3);
var _datepicker2 = _interopRequireDefault(_datepicker);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// sets up jQuery with the datepicker plugin
exports.default = _angular2.default.module('ui.date', []).constant('uiDateConfig', {}).constant('uiDateFormatConfig', '').factory('uiDateConverter', ['uiDateFormatConfig', function (uiDateFormatConfig) {
return {
stringToDate: stringToDate,
dateToString: dateToString
};
function dateToString(dateFormat, value) {
dateFormat = dateFormat || uiDateFormatConfig;
if (value) {
if (dateFormat) {
try {
return _jquery2.default.datepicker.formatDate(dateFormat, value);
} catch (formatException) {
return undefined;
}
}
if (value.toISOString) {
return value.toISOString();
}
}
return null;
}
function stringToDate(dateFormat, valueToParse) {
dateFormat = dateFormat || uiDateFormatConfig;
if (_angular2.default.isDate(valueToParse) && !isNaN(valueToParse)) {
return valueToParse;
}
if (_angular2.default.isString(valueToParse)) {
if (dateFormat) {
return _jquery2.default.datepicker.parseDate(dateFormat, valueToParse);
}
var isoDate = new Date(valueToParse);
return isNaN(isoDate.getTime()) ? null : isoDate;
}
if (_angular2.default.isNumber(valueToParse)) {
// presumably timestamp to date object
return new Date(valueToParse);
}
return null;
}
}]).directive('uiDate', ['uiDateConfig', 'uiDateConverter', function uiDateDirective(uiDateConfig, uiDateConverter) {
return {
require: '?ngModel',
link: function link(scope, element, attrs, controller) {
var $element = (0, _jquery2.default)(element);
var getOptions = function getOptions() {
return _angular2.default.extend({}, uiDateConfig, scope.$eval(attrs.uiDate));
};
var initDateWidget = function initDateWidget() {
var showing = false;
var opts = getOptions();
function setVal() {
var keys = ['Hours', 'Minutes', 'Seconds', 'Milliseconds'];
var isDate = _angular2.default.isDate(controller.$modelValue);
var preserve = {};
if (isDate && controller.$modelValue.toDateString() === $element.datepicker('getDate').toDateString()) {
return;
}
if (isDate) {
_angular2.default.forEach(keys, function (key) {
preserve[key] = controller.$modelValue['get' + key]();
});
}
var newViewValue = $element.datepicker('getDate');
if (isDate) {
_angular2.default.forEach(keys, function (key) {
newViewValue['set' + key](preserve[key]);
});
}
controller.$setViewValue(newViewValue);
}
// If we have a controller (i.e. ngModelController) then wire it up
if (controller) {
// Set the view value in a $apply block when users selects
// (calling directive user's function too if provided)
var _onSelect = opts.onSelect || _angular2.default.noop;
opts.onSelect = function (value, picker) {
scope.$apply(function () {
showing = true;
setVal();
_onSelect(value, picker);
$element.blur();
});
};
var _beforeShow = opts.beforeShow || _angular2.default.noop;
opts.beforeShow = function (input, picker) {
showing = true;
_beforeShow(input, picker);
};
var _onClose = opts.onClose || _angular2.default.noop;
opts.onClose = function (value, picker) {
showing = false;
_onClose(value, picker);
};
$element.off('blur.datepicker').on('blur.datepicker', function () {
if (!showing) {
scope.$apply(function () {
$element.datepicker('setDate', $element.datepicker('getDate'));
setVal();
});
}
});
controller.$validators.uiDateValidator = function uiDateValidator(modelValue, viewValue) {
return _angular2.default.isDate(uiDateConverter.stringToDate(attrs.uiDateFormat, viewValue));
};
controller.$parsers.push(function uiDateParser(valueToParse) {
return uiDateConverter.stringToDate(attrs.uiDateFormat, valueToParse);
});
// Update the date picker when the model changes
controller.$render = function () {
$element.datepicker('setDate', controller.$modelValue);
};
}
// Check if the $element already has a datepicker.
//
if ($element.data('datepicker')) {
// Updates the datepicker options
$element.datepicker('option', opts);
$element.datepicker('refresh');
} else {
// Creates the new datepicker widget
$element.datepicker(opts);
// Cleanup on destroy, prevent memory leaking
$element.on('$destroy', function () {
$element.datepicker('hide');
$element.datepicker('destroy');
});
}
if (controller) {
// Force a render to override whatever is in the input text box
controller.$render();
}
};
// Watch for changes to the directives options
scope.$watch(getOptions, initDateWidget, true);
}
};
}]).directive('uiDateFormat', ['uiDateConverter', function (uiDateConverter) {
return {
require: 'ngModel',
link: function link(scope, element, attrs, modelCtrl) {
var dateFormat = attrs.uiDateFormat;
// Use the datepicker with the attribute value as the dateFormat string to convert to and from a string
modelCtrl.$formatters.unshift(function (value) {
return uiDateConverter.stringToDate(dateFormat, value);
});
modelCtrl.$parsers.push(function (value) {
return uiDateConverter.dateToString(dateFormat, value);
});
}
};
}]);
/***/ },
/* 1 */
/***/ function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE_1__;
/***/ },
/* 2 */
/***/ function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE_2__;
/***/ },
/* 3 */
/***/ function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE_3__;
/***/ }
/******/ ])
});
;
//# sourceMappingURL=date.js.map

File diff suppressed because it is too large Load diff

View file

@ -1,3 +0,0 @@
var Tumblr=window.Tumblr||{};(function(){Tumblr.share_on_tumblr=function(anchor){var advanced=anchor.href.match(/(www.)?tumblr(\.com)?(\:\d{2,4})?\/share(.+)?/i);advanced=(advanced[4]!==undefined&&advanced[4].length>1);var d=document,w=window,e=w.getSelection,k=d.getSelection,x=d.selection,s=(e?e():(k)?k():(x?x.createRange().text:0)),f="http://www.tumblr.com/share",l=d.location,e=encodeURIComponent,p="?v=3&u="+e(l.href)+"&t="+e(d.title)+"&s="+e(s),u=f+p;if(advanced){u=anchor.href}try{if(!/^(.*\.)?tumblr[^.]*$/.test(l.host)){throw (0)}tstbklt()}catch(z){a=function(){if(!w.open(u,"t","toolbar=0,resizable=0,status=1,width=450,height=430")){l.href=u}};if(/Firefox/.test(navigator.userAgent)){setTimeout(a,0)}else{a()}}void (0)};Tumblr.activate_share_on_tumblr_buttons=function(){var anchors=document.getElementsByTagName("a"),anchors_length=anchors.length,match=false,old_onclick;for(var i=0;i<anchors_length;i++){match=anchors[i].href.match(/(www.)?tumblr(\.com)?(\:\d{2,4})?\/share(.+)?/i);if(match){old_onclick=anchors[i].onclick;anchors[i].onclick=function(e){Tumblr.share_on_tumblr(this);if(old_onclick){old_onclick()}old_onclick=false;e.preventDefault()}}}};(function(i){var u=navigator.userAgent;var e=
/*@cc_on!@*/
false;var st=setTimeout;if(/webkit/i.test(u)){st(function(){var dr=document.readyState;if(dr=="loaded"||dr=="complete"){i()}else{st(arguments.callee,10)}},10)}else{if((/mozilla/i.test(u)&&!/(compati)/.test(u))||(/opera/i.test(u))){document.addEventListener("DOMContentLoaded",i,false)}else{if(e){(function(){var t=document.createElement("doc:rdy");try{t.doScroll("left");i();t=null}catch(e){st(arguments.callee,0)}})()}else{window.onload=i}}}})(Tumblr.activate_share_on_tumblr_buttons)}());

View file

@ -22,10 +22,10 @@ window.handleResize = () ->
isMobile = windowWidth <= 480
$siteBody = $ '.site-body'
if window.isPlaying
$siteBody.height windowHeight - ($('.top-bar').height() + $('.now-playing').height())
else
$siteBody.height windowHeight - $('.top-bar').height()
#if window.isPlaying
# $siteBody.height windowHeight - ($('.top-bar').height() + $('.now-playing').height())
#else
# $siteBody.height windowHeight - $('.top-bar').height()
$('.dropdown-menu').each () ->
$this = $ this

View file

@ -18,6 +18,7 @@
@import 'https://fonts.googleapis.com/css?family=Roboto:400,400i,700|Material+Icons';
@import 'base/bootstrap/bootstrap';
@import (less) '../../../node_modules/angular-material/angular-material.min.css';
@import 'variables';
@import 'mixins';
@import 'layout';
@ -26,7 +27,7 @@
@import 'account-albums';
@import 'admin';
@import 'components/components';
@import 'forms';
//@import 'forms';
@import 'animations';
@import 'body';
@import 'components/player';

View file

@ -411,7 +411,6 @@ html .dropdown-menu {
}
.preview {
.img-thumbnail();
overflow: hidden;
width: 50px;
height: 50px;

View file

@ -35,6 +35,7 @@ input.search-input {
padding: 15px;
margin-bottom: 0;
height: @pfm-top-bar-size - 20px;
width: 100%;
border-radius: 2px;
.light-material-shadow(1);

View file

@ -163,7 +163,7 @@
background: #aaa;
background-size: cover;
background-position: center;
padding: 25px 25px 60px;
padding: 25px 25px 70px;
margin: -15px -15px 10px;
> img {
@ -642,7 +642,7 @@ html {
right: 10px;
width: 400px;
height: 500px;
z-index: 500;
z-index: 98;
background: #eee;
.material-shadow(2);
transition: transform 0.3s @swift-ease-in-out;
@ -688,3 +688,30 @@ canvas {
visibility: hidden;
opacity: 0;
}
.clickable {
cursor: pointer;
text-decoration: none !important;
}
md-card.album {
md-card-content {
padding: 4px 12px;
span {
font-size: 16px;
}
}
.album-stats span {
margin: 0 3px;
font-size: 12px;
md-icon {
font-size: 16px;
width: 16px;
height: 16px;
min-width: 16px;
min-height: 16px;
}
}
}

View file

@ -26,6 +26,7 @@ html body {
font-family: "Roboto", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
padding: 0px !important;
overflow: hidden;
position: initial !important;
}
header {
@ -246,7 +247,8 @@ header {
}
.site-body {
margin-top: @pfm-top-bar-size;
height: 100%;
padding-top: @pfm-top-bar-size;
}
.file-over-notice {
@ -264,8 +266,8 @@ header {
.top-bar {
display: block;
position: absolute;
z-index: 599;
background: @pfm-logo-purple;
z-index: 99;
background: @pfm-palette-500;
height: @pfm-top-bar-size;
width: 100%;
top: 0;
@ -339,3 +341,22 @@ header {
padding: 20px;
border-top: 0;
}
.account-tabs {
background: #fff;
margin: -59px -10px 5px;
border-radius: 0;
&.manage-account-tabs {
margin: 0px -10px 5px;
}
}
.checkboxes md-input-container {
margin-top: 8px;
margin-bottom: 0;
}
md-input-container#title {
margin-bottom: 0;
}

View file

@ -19,6 +19,7 @@
.site-body {
overflow-x: hidden;
padding-top: 0;
}
.now-playing {
@ -229,7 +230,7 @@
> header {
margin: 0 !important;
padding: 25px 25px 40px !important;
padding: 25px 25px 50px !important;
> img {
float: none !important;
@ -428,6 +429,10 @@
.secondary-content {
margin-top: 5px;
}
.account-tabs {
margin: -49px 0px 5px;
}
}
// Super small phones like the iPhone 5

View file

@ -24,6 +24,21 @@
@pfm-sidebar-size: 180px;
@pfm-top-bar-size: 64px;
@pfm-palette-50: rgb(245, 239, 246);
@pfm-palette-100: rgb(214, 191, 217);
@pfm-palette-200: rgb(192, 156, 196);
@pfm-palette-300: rgb(163, 111, 170);
@pfm-palette-400: rgb(150, 93, 157);
@pfm-palette-500: rgb(132, 82, 138);
@pfm-palette-600: rgb(114, 71, 119);
@pfm-palette-700: rgb(95, 59, 100);
@pfm-palette-800: rgb(77, 48, 80);
@pfm-palette-900: rgb(59, 36, 61);
@pfm-palette-A100: rgb(192, 156, 196);
@pfm-palette-A200: rgb(150, 93, 157);
@pfm-palette-A400: rgb(114, 71, 119);
@pfm-palette-A700: rgb(101, 50, 107);
// Material animation timings
@swift-ease-out: cubic-bezier(0.25, 0.8, 0.25, 1);
@swift-ease-in: cubic-bezier(0.55, 0, 0.55, 0.2);

View file

@ -49,16 +49,18 @@
<a href="/" class="logo"><img class="default-logo" src="/images/ponyfm-logo-white.svg"><img class="small-logo" src="/images/ponyfm-logo-white-nodisc.svg"></a>
<pfm-search></pfm-search>
@if (Auth::check())
<div class="user-details dropdown">
<a class="avatar dropdown-toggle" bs-dropdown href="#">
<img src="{{Auth::user()->getAvatarUrl(\Poniverse\Ponyfm\Models\Image::THUMBNAIL)}}" />
</a>
<ul class="dropdown-menu">
<li ui-sref-active="active"><a ui-sref="content.artist.profile({slug: auth.user.slug})">Your Profile</a></li>
<li ui-sref-active="active"><a ui-sref="content.artist.favourites({slug: auth.user.slug})">Favourites</a></li>
<li ui-sref-active="active"><a ui-sref="content.artist.account.settings({slug: auth.user.slug})">Account</a></li>
<li><a href="#" pfm-eat-click ng-click="logout()">Logout</a></li>
</ul>
<div class="user-details">
<md-menu md-position-mode="target-right target">
<a class="avatar dropdown-toggle" ng-click="$mdOpenMenu($event)" href="#">
<img src="{{Auth::user()->getAvatarUrl(\Poniverse\Ponyfm\Models\Image::THUMBNAIL)}}" />
</a>
<md-menu-content width="3">
<md-menu-item><md-button ui-sref="content.artist.profile({slug: auth.user.slug})">Your Profile</md-button></md-menu-item>
<md-menu-item><md-button ui-sref="content.artist.favourites({slug: auth.user.slug})">Favourites</md-button></md-menu-item>
<md-menu-item><md-button ui-sref="content.artist.account.settings({slug: auth.user.slug})">Account</md-button></md-menu-item>
<md-menu-item><md-button href="#" pfm-eat-click ng-click="logout()">Logout</md-button></md-menu-item>
</ul>
</md-menu>
</div>
<div class="notification-menu">
<a href="#" ng-click="notifPulloutToggle()"><i class="material-icons">notifications</i></a>