mirror of
https://github.com/Poniverse/Pony.fm.git
synced 2024-11-22 04:58:01 +01:00
Basic mobile support (#81)
Mobile specific view. Basically Pony.fm desktop squashed into a mobile view
This commit is contained in:
parent
87d25bb8b8
commit
ca397f09fc
12 changed files with 311 additions and 40 deletions
BIN
public/images/icons/app-icon-144.png
Normal file
BIN
public/images/icons/app-icon-144.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
BIN
public/images/icons/app-icon-192.png
Normal file
BIN
public/images/icons/app-icon-192.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
public/images/icons/app-icon-96.png
Normal file
BIN
public/images/icons/app-icon-96.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.8 KiB |
24
public/manifest.json
Normal file
24
public/manifest.json
Normal file
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"short_name": "Pony.fm",
|
||||
"name": "Pony.fm",
|
||||
"icons": [
|
||||
{
|
||||
"src": "images/icons/app-icon-96.png",
|
||||
"sizes": "96x96",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "images/icons/app-icon-144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "images/icons/app-icon-192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
"orientation": "portrait"
|
||||
}
|
47
public/service-worker.js
Normal file
47
public/service-worker.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
// 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/>.
|
||||
|
||||
var urlsToCache = [
|
||||
'/',
|
||||
'/build/styles/app.css',
|
||||
'/build/scripts/app.js',
|
||||
'/build/scripts/templates.js',
|
||||
'/templates/directives/player.html',
|
||||
'/templates/directives/search.html',
|
||||
'/templates/directives/tracks-list.html',
|
||||
'/templates/directives/users-list.html',
|
||||
'/templates/directives/albums-list.html',
|
||||
'/templates/directives/playlists-list.html',
|
||||
'/templates/home/index.html',
|
||||
|
||||
];
|
||||
|
||||
var CACHE_NAME = 'pfm-cache-v1';
|
||||
|
||||
// Set the callback for the install step
|
||||
self.addEventListener('install', function(event) {
|
||||
// Doesn't do anything right now
|
||||
// Could never get offline to fully
|
||||
// work without bugs :(
|
||||
|
||||
// Perform install steps
|
||||
event.waitUntil(
|
||||
caches.open(CACHE_NAME)
|
||||
.then(function(cache) {
|
||||
console.log('Opened cache');
|
||||
})
|
||||
);
|
||||
});
|
|
@ -21,9 +21,20 @@ module.exports = angular.module('ponyfm').controller "application", [
|
|||
$scope.$state = $state
|
||||
$scope.$stateParams = $stateParams
|
||||
$scope.isPinnedPlaylistSelected = false
|
||||
$scope.menuActive = false
|
||||
$loadingElement = null
|
||||
loadingStateName = null
|
||||
|
||||
if 'serviceWorker' of navigator
|
||||
console.log 'Service Worker is supported'
|
||||
navigator.serviceWorker.register('service-worker.js').then((reg) ->
|
||||
console.log 'SW registered', reg
|
||||
).catch (err) ->
|
||||
console.log 'SW register failed', err
|
||||
|
||||
$scope.menuToggle = () ->
|
||||
$scope.menuActive = !$scope.menuActive
|
||||
|
||||
if window.pfm.error
|
||||
$state.transitionTo 'errors-' + window.pfm.error
|
||||
|
||||
|
@ -60,6 +71,7 @@ module.exports = angular.module('ponyfm').controller "application", [
|
|||
|
||||
statesPreloaded = {}
|
||||
$scope.$on '$stateChangeStart', (e, newState, newParams, oldState, oldParams) ->
|
||||
$scope.menuActive = false
|
||||
$scope.isPinnedPlaylistSelected = false
|
||||
|
||||
if newState.name == 'content.playlist'
|
||||
|
|
|
@ -16,7 +16,13 @@
|
|||
|
||||
window.handleResize = () ->
|
||||
windowHeight = $(window).height()
|
||||
windowWidth = $(window).width()
|
||||
isMobile = windowWidth <= 480
|
||||
$siteBody = $ '.site-body'
|
||||
|
||||
if isMobile
|
||||
$siteBody.height windowHeight - $('.now-playing').height() * 2
|
||||
else
|
||||
$siteBody.height windowHeight - $('header').height()
|
||||
|
||||
$('.dropdown-menu').each () ->
|
||||
|
@ -26,6 +32,7 @@ window.handleResize = () ->
|
|||
'max-height': newMaxHeight
|
||||
|
||||
$('.stretch-to-bottom').each () ->
|
||||
if !isMobile
|
||||
$this = $ this
|
||||
newHeight = windowHeight - $this.offset().top
|
||||
if newHeight > 0
|
||||
|
|
1
resources/assets/styles/app.less
vendored
1
resources/assets/styles/app.less
vendored
|
@ -36,3 +36,4 @@
|
|||
@import 'components/uploader';
|
||||
@import 'components/search';
|
||||
@import 'components/track-editor';
|
||||
@import 'mobile';
|
||||
|
|
101
resources/assets/styles/layout.less
vendored
101
resources/assets/styles/layout.less
vendored
|
@ -31,35 +31,7 @@ html body {
|
|||
}
|
||||
|
||||
header {
|
||||
> a {
|
||||
display: block;
|
||||
float: left;
|
||||
width: (@pfm-sidebar-size);
|
||||
height: 64px;
|
||||
line-height: 42px;
|
||||
background: #84528A;
|
||||
color: #fff;
|
||||
font-size: 24pt;
|
||||
font-weight: lighter;
|
||||
position: relative;
|
||||
z-index: 600;
|
||||
font-family: 'Josefin Sans', sans-serif;
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
background: darken(#84528A, 25%);
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
img.logo {
|
||||
padding-left: 6px;
|
||||
width: 100%;
|
||||
max-width: 90%;
|
||||
padding-top: 13px;
|
||||
max-height: 45%
|
||||
}
|
||||
}
|
||||
|
||||
.user-details {
|
||||
float: right;
|
||||
|
@ -116,15 +88,46 @@ header {
|
|||
}
|
||||
|
||||
.sidebar {
|
||||
> a {
|
||||
display: block;
|
||||
float: left;
|
||||
width: (@pfm-sidebar-size);
|
||||
height: 64px;
|
||||
line-height: 42px;
|
||||
background: #84528A;
|
||||
color: #fff;
|
||||
font-size: 24pt;
|
||||
font-weight: lighter;
|
||||
position: relative;
|
||||
z-index: 600;
|
||||
font-family: 'Josefin Sans', sans-serif;
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
background: darken(#84528A, 25%);
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
img.logo {
|
||||
padding-left: 6px;
|
||||
width: 100%;
|
||||
max-width: 90%;
|
||||
padding-top: 13px;
|
||||
max-height: 45%
|
||||
}
|
||||
}
|
||||
|
||||
background: #515151;
|
||||
width: @pfm-sidebar-size;
|
||||
height: 100%;
|
||||
float: left;
|
||||
list-style: none;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
font-size: 10pt;
|
||||
position: relative;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
|
||||
li {
|
||||
margin: 0px;
|
||||
|
@ -251,3 +254,41 @@ header {
|
|||
.chart-btn-container {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.mobile-header {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.burger-wrapper {
|
||||
top:20px;
|
||||
left: 20px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.burger {
|
||||
width: 25px;
|
||||
height: 20px;
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
}
|
||||
|
||||
.bun-top,.meat,.bun-bottom {
|
||||
position: absolute;
|
||||
display: block;
|
||||
border-radius: 4px;
|
||||
background: white;
|
||||
width: 25px;
|
||||
height: 2px;
|
||||
}
|
||||
|
||||
.bun-top {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.meat {
|
||||
top: 9px;
|
||||
}
|
||||
|
||||
.bun-bottom {
|
||||
bottom: 0;
|
||||
}
|
||||
|
|
127
resources/assets/styles/mobile.less
vendored
Normal file
127
resources/assets/styles/mobile.less
vendored
Normal file
|
@ -0,0 +1,127 @@
|
|||
@media only screen and (max-width: 480px) {
|
||||
html, body {
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
body > header {
|
||||
margin-top: 64px;
|
||||
}
|
||||
|
||||
.site-content {
|
||||
margin-left: 0px;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.now-playing {
|
||||
margin-left: 0px;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
bottom: 0;
|
||||
z-index: 1010;
|
||||
box-shadow: 0 0 8px rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.user-details {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 1002;
|
||||
}
|
||||
|
||||
.mobile-header {
|
||||
display: block !important;
|
||||
position: absolute;
|
||||
z-index: 1001;
|
||||
background: #84528A;
|
||||
height: 64px;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
|
||||
.logo {
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
height: 40px;
|
||||
width: 160px;
|
||||
padding-top: 16px;
|
||||
|
||||
> img {
|
||||
max-height: 75%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
left: -170px;
|
||||
transition: transform 0.5s ease;
|
||||
transform: translateX(0px) translateZ(0);
|
||||
perspective: 1000;
|
||||
backface-visibility: hidden;
|
||||
will-change: transform;
|
||||
z-index: 1011;
|
||||
height: ~"calc(100% - 64px)";
|
||||
box-shadow: 0 8px 8px rgba(0,0,0,0.5);
|
||||
|
||||
> a {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar.active {
|
||||
transform: translateX(170px) translateZ(0);
|
||||
}
|
||||
|
||||
.user-details > .avatar {
|
||||
border: 0 !important;
|
||||
box-shadow: initial !important;
|
||||
background: transparent !important;
|
||||
|
||||
> img {
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
> span {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.track-player {
|
||||
margin-right: 0px !important;
|
||||
.buttons {
|
||||
li.volume, li.status {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
input.search-input {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.dropdowns {
|
||||
margin-bottom: 0px;
|
||||
> li {
|
||||
margin-bottom: 10px;
|
||||
> .btn {
|
||||
font-size: 10pt;
|
||||
}
|
||||
}
|
||||
}
|
||||
.details-columns {
|
||||
.cboxElement {
|
||||
display: none;
|
||||
}
|
||||
.right {
|
||||
float: none;
|
||||
padding: 0px;
|
||||
width: auto;
|
||||
}
|
||||
.left {
|
||||
margin-right: 0px;
|
||||
margin-left: 0px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -42,9 +42,16 @@
|
|||
</script>
|
||||
|
||||
<header>
|
||||
<a href="/">
|
||||
<img src="/images/ponyfm-logo-white.svg" class="logo">
|
||||
</a>
|
||||
<div class="mobile-header">
|
||||
<div class="burger-wrapper" ng-click="menuToggle()">
|
||||
<div class="burger">
|
||||
<div class="bun-top"></div>
|
||||
<div class="meat"></div>
|
||||
<div class="bun-bottom"></div>
|
||||
</div>
|
||||
</div>
|
||||
<a href="/" class="logo"><img src="/images/ponyfm-logo-white.svg"></a>
|
||||
</div>
|
||||
<div class="now-playing">
|
||||
@if (Auth::check())
|
||||
<div class="user-details dropdown">
|
||||
|
@ -65,7 +72,10 @@
|
|||
</header>
|
||||
|
||||
<div class="site-body">
|
||||
<ul class="sidebar" ng-controller="sidebar">
|
||||
<ul class="sidebar" ng-controller="sidebar" ng-class="{'active': menuActive}">
|
||||
<a href="/">
|
||||
<img src="/images/ponyfm-logo-white.svg" class="logo">
|
||||
</a>
|
||||
<li><pfm-search></pfm-search></li>
|
||||
<li ng-class="{selected: stateIncludes('content.tracks') || stateIncludes('content.track')}"><a href="/tracks">Tracks</a></li>
|
||||
<li ng-class="{selected: stateIncludes('content.albums') || stateIncludes('content.album')}"><a href="/albums">Albums</a></li>
|
||||
|
|
|
@ -21,7 +21,9 @@
|
|||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<title ng-bind="title">Pony.fm</title>
|
||||
<meta name="description" content="@{{ description }}" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
|
||||
<meta name="theme-color" content="#84528A" />
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
<base href="/" />
|
||||
|
||||
@yield('styles')
|
||||
|
|
Loading…
Reference in a new issue