Update dev environment & add media player notifications (#139)

This changeset's key new feature is allowing web browsers to display media player notifications for Pony.fm by implementing the media session API. These notifications display Play/Pause, Previous, and Next controls that control Pony.fm's playback. This also makes Pony.fm controllable by automotive audio systems and other Bluetooth devices that expose their own (often physical) playback controls.

Other improvements in this changeset include:

- Update the automated dev environment setup to work in 2021

- Remove extraneous frontend logging

- Fix to consistently include album data with a track's data
This commit is contained in:
Alex I. Ramirez 2021-01-01 22:29:36 -08:00 committed by GitHub
parent 9f311c949f
commit f64400c46d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 10293 additions and 15768 deletions

View file

@ -57,6 +57,8 @@ Asset pipeline
Pony.fm uses [gulp](http://gulpjs.com/) to mange its asset pipeline. Pony.fm uses [gulp](http://gulpjs.com/) to mange its asset pipeline.
**In macOS**, you must have XCode Command Line Tools installed. This may be downloaded at [https://developer.apple.com/download/more/?=command%20line%20tools](https://developer.apple.com/download/more/?=command%20line%20tools)
**Important:** Run `npm` and `gulp` from your host machine and not within the VM. You must first have it installed globally: **Important:** Run `npm` and `gulp` from your host machine and not within the VM. You must first have it installed globally:
npm install -g gulp npm install -g gulp

2
Vagrantfile vendored
View file

@ -4,7 +4,7 @@ Vagrant.configure("2") do |config|
config.hostmanager.manage_host = true config.hostmanager.manage_host = true
config.vm.box = 'laravel/homestead' config.vm.box = 'laravel/homestead'
config.vm.box_version = '0.4.2' config.vm.box_version = '10.1.1'
config.vm.provider "virtualbox" do |v| config.vm.provider "virtualbox" do |v|
v.cpus = 4 v.cpus = 4

View file

@ -507,13 +507,6 @@ class Track extends Model implements Searchable, Commentable, Favouritable
$returnValue['comments'] = $comments; $returnValue['comments'] = $comments;
if ($track->album_id != null) {
$returnValue['album'] = [
'title' => $track->album->title,
'url' => $track->album->url,
];
}
$formats = []; $formats = [];
foreach ($track->trackFiles as $trackFile) { foreach ($track->trackFiles as $trackFile) {
@ -570,7 +563,7 @@ class Track extends Model implements Searchable, Commentable, Favouritable
]; ];
} }
return [ $data = [
'id' => (int) $track->id, 'id' => (int) $track->id,
'title' => $track->title, 'title' => $track->title,
'user' => [ 'user' => [
@ -619,6 +612,15 @@ class Track extends Model implements Searchable, Commentable, Favouritable
'edit' => Gate::allows('edit', $track) 'edit' => Gate::allows('edit', $track)
] ]
]; ];
if ($track->album_id != null) {
$data['album'] = [
'title' => $track->album->title,
'url' => $track->album->url,
];
}
return $data;
} }
/** /**

View file

@ -272,53 +272,50 @@ gulp.task("email-inline", function emailInline() {
// Helper tasks for email watchers // Helper tasks for email watchers
gulp.task("email-rebuild-handlebars", function(callback){ gulp.task("email-rebuild-handlebars", gulp.series("email-pages", "email-inline", function(callback){
runSequence("email-pages", "email-inline", callback); callback();
}); }));
gulp.task("email-rebuild-layouts", function(callback){ gulp.task("email-rebuild-layouts", gulp.series("email-reset-pages", "email-pages", "email-inline", function(callback){
runSequence("email-reset-pages", "email-pages", "email-inline", callback); callback();
}); }));
gulp.task("email-rebuild-sass", function(callback){ gulp.task("email-rebuild-sass", gulp.series("email-reset-pages", "email-sass", "email-pages", "email-inline", function(callback){
runSequence("email-reset-pages", "email-sass", "email-pages", "email-inline", callback) callback();
}); }));
// Watch for file changes // Watch for file changes
gulp.task("email-watch", function (callback) { gulp.task("email-watch", function (callback) {
gulp.watch('resources/emails/src/pages/**/*.blade.php.hbs', ["email-rebuild-handlebars"]); gulp.watch('resources/emails/src/pages/**/*.blade.php.hbs', gulp.parallel("email-rebuild-handlebars"));
gulp.watch(['resources/emails/src/layouts/**/*', 'resources/emails/src/partials/**/*'], ["email-rebuild-layouts"]); gulp.watch(['resources/emails/src/layouts/**/*', 'resources/emails/src/partials/**/*'], gulp.parallel("email-rebuild-layouts"));
gulp.watch(['resources/emails/src/assets/scss/**/*.scss'], ["email-rebuild-sass"]); gulp.watch(['resources/emails/src/assets/scss/**/*.scss'], gulp.parallel("email-rebuild-sass"));
gulp.watch('resources/emails/src/assets/img/**/*', ["email-images"]); gulp.watch('resources/emails/src/assets/img/**/*', gulp.parallel("email-images"));
callback(); callback();
}); });
// Build the "resources/views/emails/html" folder by running all of the above tasks // Build the "resources/views/emails/html" folder by running all of the above tasks
gulp.task('email-build', function(callback){ gulp.task('email-build', gulp.series(("email-clean", "email-pages", "email-sass", "email-images", "email-inline", function(callback){
runSequence("email-clean", "email-pages", "email-sass", "email-images", "email-inline", callback); callback();
}); })));
// Build emails, run the server, and watch for file changes // Build emails, run the server, and watch for file changes
gulp.task('email-default', function(callback) { gulp.task('email-default', gulp.series('email-build', "email-watch", function(callback) {
runSequence('email-build', "email-watch");
callback(); callback();
}); }));
//=============== END Zurb Foundation Email stack =================// //=============== END Zurb Foundation Email stack =================//
gulp.task('build', [ gulp.task('build', gulp.parallel('webpack-build',
'webpack-build',
'copy:templates', 'copy:templates',
'styles-app', 'styles-app',
'styles-embed', 'styles-embed',
'email-build' 'email-build'));
]);
gulp.task("watch-legacy", ["build"], function () {
gulp.watch("resources/assets/styles/**/*.{css,less}", ["styles-app"]);
});
gulp.task("watch", ["webpack-dev-server", "email-default", "watch-legacy"], function () {}); gulp.task("watch-legacy", gulp.series(gulp.parallel("build"), function () {
gulp.watch("resources/assets/styles/**/*.{css,less}", gulp.parallel("styles-app"));
}));
gulp.task("watch", gulp.parallel("webpack-dev-server", "email-default", "watch-legacy"));
function endsWith(str, suffix) { function endsWith(str, suffix) {
return str.indexOf(suffix, str.length - suffix.length) !== -1; return str.indexOf(suffix, str.length - suffix.length) !== -1;

27802
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -19,7 +19,7 @@
"del": "^2.2.2", "del": "^2.2.2",
"foundation-emails": "^2.2.1", "foundation-emails": "^2.2.1",
"fs": "0.0.1-security", "fs": "0.0.1-security",
"gulp": "^3.9.1", "gulp": "^4.0.2",
"gulp-angular-templatecache": "1.8.0", "gulp-angular-templatecache": "1.8.0",
"gulp-autoprefixer": "3.1.0", "gulp-autoprefixer": "3.1.0",
"gulp-cached": "1.1.0", "gulp-cached": "1.1.0",

View file

@ -66,6 +66,7 @@ module.exports = angular.module('ponyfm').factory('player', [
onplay: () -> $rootScope.safeApply -> onplay: () -> $rootScope.safeApply ->
track.isPlaying = true track.isPlaying = true
broadcastMediaInfo track
onresume: () -> $rootScope.safeApply -> onresume: () -> $rootScope.safeApply ->
track.isPlaying = true track.isPlaying = true
@ -81,6 +82,32 @@ module.exports = angular.module('ponyfm').factory('player', [
self.canGoNext = self.playlistIndex < self.playlist.length - 1 self.canGoNext = self.playlistIndex < self.playlist.length - 1
self.canGoPrev = self.playlistIndex > 0 self.canGoPrev = self.playlistIndex > 0
broadcastMediaInfo = (track) ->
if 'mediaSession' of navigator
navigator.mediaSession.metadata = new MediaMetadata(
title: track['title']
artist: track.user.name
album: if 'album' of track then track.album.title else 'Unknown Album'
artwork: [
{src: track.covers.original, sizes: '350x350', type: 'image/png'},
{src: track.covers.small, sizes: '100x100', type: 'image/png'}
{src: track.covers.thumbnail, sizes: '50x50', type: 'image/png'}
]
navigator.mediaSession.setActionHandler(
'play'
(() -> self.currentSound.play()))
navigator.mediaSession.setActionHandler(
'pause'
(() -> self.currentSound.pause()))
navigator.mediaSession.setActionHandler(
'previoustrack'
(() -> self.playPrev()))
navigator.mediaSession.setActionHandler(
'nexttrack'
(() -> self.playNext()))
)
self = self =
ready: false ready: false
isPlaying: false isPlaying: false

View file

@ -1,12 +1,15 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Homestead v10 defaults the "php" command to PHP 7.4. Pony.fm needs 7.0.
sudo ln -sf /usr/bin/php7.0 /usr/bin/php
if type java &>/dev/null; then if type java &>/dev/null; then
echo "Java is installed!" echo "Java is installed!"
else else
sudo add-apt-repository -y ppa:webupd8team/java #sudo apt-get install -y wget apt-transport-https gnupg
echo /usr/bin/debconf shared/accepted-oracle-license-v1-1 select true | sudo debconf-set-selections wget -qO - https://adoptopenjdk.jfrog.io/adoptopenjdk/api/gpg/key/public | sudo apt-key add -
echo /usr/bin/debconf shared/accepted-oracle-license-v1-1 seen true | sudo debconf-set-selections echo "deb https://adoptopenjdk.jfrog.io/adoptopenjdk/deb focal main" | sudo tee /etc/apt/sources.list.d/adoptopenjdk.list
fi fi
@ -14,32 +17,34 @@ if type /usr/share/elasticsearch/bin/elasticsearch &>/dev/null; then
echo "ElasticSearch is installed!" echo "ElasticSearch is installed!"
else else
wget -qO - https://packages.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add - wget -qO - https://packages.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
echo "deb http://packages.elastic.co/elasticsearch/2.x/debian stable main" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-2.x.list echo "deb http://packages.elastic.co/elasticsearch/2.x/debian stable main" | sudo tee /etc/apt/sources.list.d/elasticsearch-2.x.list
fi fi
echo "Running apt-get update..." echo "Running apt-get update..."
sudo apt-get -qq update sudo apt-get update
echo "Installing tagging tools & other dependencies..." echo "Installing tagging tools & other dependencies..."
sudo apt-get -qq install -y AtomicParsley flac vorbis-tools imagemagick oracle-java8-installer elasticsearch pkg-config yasm libfaac-dev libmp3lame-dev libvorbis-dev libtheora-dev sudo apt-get install -y elasticsearch
sudo apt-get install -y atomicparsley flac vorbis-tools imagemagick adoptopenjdk-8-openj9 pkg-config yasm libfaac-dev libmp3lame-dev libvorbis-dev libtheora-dev
echo "Installing PHP extensions" echo "Installing PHP extensions"
sudo apt-get -qq install -y libgmp-dev php-gmp php7.0-gmp sudo apt-get install -y libgmp-dev php-gmp php7.0-gmp
echo "Installing Postgres migration tool" echo "Installing Postgres migration tool"
sudo apt-get -qq install -y pgloader sudo apt-get install -y pgloader
if type ffmpeg &>/dev/null; then if type ffmpeg &>/dev/null; then
echo "ffmpeg is installed!" echo "ffmpeg is installed!"
else else
echo "ffmpeg is not installed; compiling..." echo "ffmpeg is not installed; downloading..."
cd /tmp cd /tmp
wget "https://ffmpeg.org/releases/ffmpeg-2.6.3.tar.bz2" wget -q "https://ffmpeg.org/releases/ffmpeg-2.6.3.tar.bz2"
echo "Finished downloading ffmpeg; now compiling it..."
tar -xjf "ffmpeg-2.6.3.tar.bz2" tar -xjf "ffmpeg-2.6.3.tar.bz2"
cd "ffmpeg-2.6.3" cd "ffmpeg-2.6.3"
./configure --enable-gpl --enable-encoder=flac --enable-encoder=alac --enable-libmp3lame --enable-libvorbis --enable-libtheora --enable-libfaac --enable-nonfree sudo ./configure --enable-gpl --enable-encoder=flac --enable-encoder=alac --enable-libmp3lame --enable-libvorbis --enable-libtheora --enable-libfaac --enable-nonfree
make -j4 sudo make -j4
sudo make install sudo make install
fi fi