Skip to content

Commit

Permalink
Make Mixtube Open Source easily cutomisable for commercial deployment (
Browse files Browse the repository at this point in the history
…mixtube#24)

- Removed non OS assets (logo mainly)
- Introduced a configurable build system
- Updated some dependencies
  • Loading branch information
Jonathan Raoult authored Feb 8, 2017
1 parent 2d08bb1 commit 94c6b34
Show file tree
Hide file tree
Showing 89 changed files with 892 additions and 560 deletions.
42 changes: 41 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,47 @@ You will also need your own YouTube Data API key set into the environment variab
You need npm installed on your machine. Then execute:
```
npm install
MIXTUBE_YOUTUBE_API_KEY=<your YouTube data api key> npm run serve
MIXTUBE_YOUTUBE_API_KEY=<your YouTube data api key> npm start
```

The server should be running by now and you can access MixTube at https://localhost:3000

## Building

### Basics

The Mixtube project is split between the directories `app` and `build`. The `app` directory contains only app specific
sources and `build` only build specific sources. You don't have to think about that too much since the root of the
project contains NPM scripts to help getting started with MixTube for different scenarios:
- `npm run debug` is an alias of `npm start` (more precisely, the other way around)
- `deploy:gh` makes a production build and deploys it to the repository `origin`'s GitHub page.It assumes the
repository is named `mixtube`

### Advanced

If you want to build with a better control over the settings the best is to invoke the gulp script directly:

```
cd build
node_modules/.bin/gulp [--watch] [--serve] [--baseUrl <string>]
```

You can provides different arguments to turn on / off certain behaviours:

- **watch** watches for source changes and automatically rebuild (`boolean`, `false` by default)
- **serve** turns on the local server (`boolean`, `false` by default)
- **production** turns on minification and inlining of "critical path css" (`boolean`, `false` by default)
- **publicDirPath** specifies the output directory for the build (`string`, `public` by default)
- **baseUrl** specifies the base URL to use for all relative URLs (`string`, `/` by default)
- **appColor** specifies the accent color for the whole application (`string`, `hsl(199, 100%, 50%)` by default)
- **errorsTrackerPath** overrides the default error tracker implementation (`string`). A console logging implementation
will be use if the argument is not defined
- **analyticsTrackerPath** overrides the default analytics tracker implementation (`string`). A noop default
implementation will be use if the argument is not defined
- **logoPath**: specifies the logo of the application (`string`, `src/images/mt-empty-logo.svg` by default)

You can always get the descriptions of the build options by invoking:

```
node_modules/.bin/gulp help
```
File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 0 additions & 6 deletions app/images/mt-logo.svg

This file was deleted.

21 changes: 21 additions & 0 deletions app/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "mixtube-app",
"description": "Mixtube application module",
"private": true,
"repository": {
"type": "git",
"url": "https://github.com/jraoult/mixtube.git"
},
"license": "MIT",
"dependencies": {
"Ionicons": "jraoult/ionicons#npm",
"angular": "^1.4.5",
"angular-animate": "^1.4.5",
"angular-aria": "^1.4.5",
"fg-loadcss": "^1.2.1",
"keymaster": "^1.6.2",
"lodash": "^4.15.0",
"mixtube-playback": "mixtube/mixtube-playback#v1.0.1",
"scroll-into-view": "^1.5.0"
}
}
3 changes: 0 additions & 3 deletions app/scripts/main.js

This file was deleted.

3 changes: 3 additions & 0 deletions app/src/images/mt-empty-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
File renamed without changes
106 changes: 22 additions & 84 deletions app/index.html → app/src/index.html
Original file line number Diff line number Diff line change
@@ -1,93 +1,38 @@
<!DOCTYPE html>
<html ng-controller="RootCtrl as rootCtrl">
<html ng-controller="RootCtrl as rootCtrl" data-appVersion="<%= appVersion %>" lang="en">
<head>
<base href="<%= baseUrl %>">
<!--hopefully triggers GPU Rasterization on Chrome-->
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<meta name="viewport" content="width=device-width, minimum-scale=1.0">

<title ng-bind="'MixTube' + (rootCtrl.queueLoading ? ' (loading)' : '')">MixTube</title>
<meta name="description" content="MixTube, A video queue app for your parties">

<meta name="twitter:card" value="summary">

<meta property="og:title" content="My video playlist on MixTube">
<meta property="og:type" content="video.other">
<meta property="og:description" content="Discover my video playlist on MixTube and enjoy the mix with your friends">
<meta property="og:site_name" content="MixTube.io">
<meta property="og:image" content="http://www.mixtube.io/mixtube-logo-og.png">

<!-- build:favicons -->
<!--the favicons related meta will be inserted here-->
<!-- endbuild -->

<link href='https://fonts.gstatic.com' rel='preconnect' crossorigin>
<link href='https://www.googleapis.com' rel='preconnect'>
<link href='https://s.ytimg.com' rel='preconnect'>
<link href='https://i.ytimg.com' rel='preconnect'>

<script>
<script id="load-css-script">
'use strict';

/*!
loadCSS: load a CSS file asynchronously.
[c]2014 @scottjehl, Filament Group, Inc.
Licensed MIT
*/
function loadCSS(href, before, media, callback) {
// Arguments explained:
// `href` is the URL for your CSS file.
// `before` optionally defines the element we'll use as a reference for injecting our <link>
// By default, `before` uses the first <script> element in the page.
// However, since the order in which stylesheets are referenced matters, you might need a more specific location in your document.
// If so, pass a different reference element to the `before` argument and it'll insert before that instead
// note: `insertBefore` is used instead of `appendChild`, for safety re: http://www.paulirish.com/2011/surefire-dom-element-insertion/
var ss = window.document.createElement("link");
var ref = before || window.document.getElementsByTagName("script")[0];
var sheets = window.document.styleSheets;
ss.rel = "stylesheet";
ss.href = href;
// temporarily, set media to something non-matching to ensure it'll fetch without blocking render
ss.media = "only x";
// DEPRECATED
if (callback) {
ss.onload = callback;
}

// inject link
ref.parentNode.insertBefore(ss, ref);
// This function sets the link's media back to `all` so that the stylesheet applies once it loads
// It is designed to poll until document.styleSheets includes the new sheet.
ss.onloadcssdefined = function(cb) {
var defined;
for (var i = 0; i < sheets.length; i++) {
if (sheets[i].href && sheets[i].href.indexOf(href) > -1) {
defined = true;
}
}
if (defined) {
cb();
}
else {
setTimeout(function() {
ss.onloadcssdefined(cb);
});
}
};
ss.onloadcssdefined(function() {
ss.media = media || "all";
});
return ss;
}
<!-- build:loadCssScript -->
<!-- the Filament Group loadCSS script will be inserted here -->
<!-- endbuild -->

// make sure cached CSS don't get processed straight and then block first paint
window.requestAnimationFrame(function() {
loadCSS('styles/main.css');
loadCSS('//fonts.googleapis.com/css?family=Open+Sans:300,600');
var loadCssScriptElement = document.getElementById('load-css-script');
loadCSS('main.css', loadCssScriptElement);
loadCSS('//fonts.googleapis.com/css?family=Open+Sans:300,600', loadCssScriptElement);
});
</script>

<!-- build:cssInline -->
<!--the "above the fold" css will be inseretd here-->
<!-- the "above the fold" css will be inserted here -->
<!-- endbuild -->

<!-- build:headInject -->
<!-- some extra HTML code can be inserted here if specified at build time -->
<!-- endbuild -->
</head>
<body ng-class="{idle: rootCtrl.shouldIdleChrome()}">
Expand Down Expand Up @@ -118,22 +63,20 @@
<div class="mt-header__container">
<div class="start">
<h1 class="mt-header__app-title">
<svg class="mt-svg-icon" role="img" title="MixTube">
<use xlink:href="images/sprite.svg#mt-logo"></use>
</svg>
<img class="mt-header__app-title__logo" alt="MixTube logo" src="<%= logoUrl %>">
</h1>
</div>
<div class="center">
<div class="mt-header__playback-button" ng-click="rootCtrl.togglePlayback()"
ng-show="rootCtrl.shouldShowPlaybackControls()">
<div class="facet facet__animation-toggle" ng-class="{toggle: !rootCtrl.isPlaying()}">
<svg class="mt-svg-icon" role="img" title="Play">
<use xlink:href="images/sprite.svg#mt-play-circle"></use>
<use xlink:href="sprite.svg#mt-play-circle"></use>
</svg>
</div>
<div class="facet facet__animation-toggle" ng-class="{toggle: rootCtrl.isPlaying()}">
<svg class="mt-svg-icon" role="img" title="Pause">
<use xlink:href="images/sprite.svg#mt-pause-circle"></use>
<use xlink:href="sprite.svg#mt-pause-circle"></use>
</svg>
</div>
</div>
Expand All @@ -145,12 +88,12 @@ <h1 class="mt-header__app-title">
<div class="mt-search-input__button" ng-click="rootCtrl.toggleSearch()">
<div class="facet facet__animation-toggle" ng-class="{toggle: !rootCtrl.isSearchShown()}">
<svg class="mt-svg-icon" role="img" title="Open search">
<use xlink:href="images/sprite.svg#ios-search"></use>
<use xlink:href="sprite.svg#ios-search"></use>
</svg>
</div>
<div class="facet facet__animation-toggle" ng-class="{toggle: rootCtrl.isSearchShown()}">
<svg class="mt-svg-icon" role="img" title="Close search">
<use xlink:href="images/sprite.svg#ios-close-empty"></use>
<use xlink:href="sprite.svg#ios-close-empty"></use>
</svg>
</div>
</div>
Expand Down Expand Up @@ -199,7 +142,7 @@ <h1 class="mt-header__app-title">
<div class="mt-queue__entry__remove-button" ng-click="queueCtrl.removeQueueEntry(entry)"
mt-click-active-class="ng-click-active">
<svg class="mt-svg-icon" role="img" title="Remove">
<use xlink:href="images/sprite.svg#ios-close"></use>
<use xlink:href="sprite.svg#ios-close"></use>
</svg>
</div>
</div>
Expand Down Expand Up @@ -236,7 +179,7 @@ <h3>Results from {{pLabel}}:</h3>
<div class="loading-indicator">
<span class="facet facet__animation-toggle" ng-hide="rootCtrl.isPlaying()">
<svg class="mt-svg-icon" role="img" title="Loading video thumbnail">
<use xlink:href="images/sprite.svg#ios-videocam"></use>
<use xlink:href="sprite.svg#ios-videocam"></use>
</svg>
</span>
</div>
Expand Down Expand Up @@ -304,12 +247,7 @@ <h3>Results from {{pLabel}}:</h3>
</div>
</div>

<script src="scripts/main.js"></script>
<script>
'use strict';

mixtube({youtubeAPIKey: '<%= youtubeApiKey %>'});
</script>
<script src="main.js"></script>
<script src="https://www.youtube.com/iframe_api" defer></script>

</body>
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ function capabilitiesFactory($rootScope, $document, $timeout, configuration) {
}

function activate() {
loadScript('scripts/components/capabilities/videoCallPlayTest.js');
loadScript('components/capabilities/videoCallPlayTest.js');
}

// the video auto play test expects this property to be defined
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';

var has = require('lodash/object/has'),
isUndefined = require('lodash/lang/isUndefined');
var has = require('lodash/has'),
isUndefined = require('lodash/isUndefined');

// @ngInject
function configurationFactory($location, environment) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

var padLeft = require('lodash/string/padLeft');
var padStart = require('lodash/padStart');

// a duration formatter that takes a duration in milliseconds and returns a formatted duration like "h:mm"
function durationFilter() {
Expand All @@ -20,7 +20,7 @@ function durationFilter() {
singletonDate.setMilliseconds(time);

return (singletonDate.getHours() * 60 + singletonDate.getMinutes()).toString(10) + ':' +
padLeft(singletonDate.getSeconds().toString(10), 2, '0');
padStart(singletonDate.getSeconds().toString(10), 2, '0');
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';

var keymaster = require('keymaster'),
isUndefined = require('lodash/lang/isUndefined');
isUndefined = require('lodash/isUndefined');

// @ngInject
function keyboardShortcutManagerFactory($rootScope) {
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

var pull = require('lodash/array/pull');
var pull = require('lodash/pull');

// brfs requires this to be on its own line
var fs = require('fs');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
'use strict';

var angular = require('angular'),
difference = require('lodash/array/difference'),
includes = require('lodash/collection/includes'),
difference = require('lodash/difference'),
includes = require('lodash/includes'),
mixtubePlayback = require('mixtube-playback');

// @ngInject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ var angular = require('angular'),
Queue = require('./queueModel').Queue,
QueueEntry = require('./queueModel').QueueEntry,
DeserializationErrorCodes = require('./deserializationErrorCodes'),
uniqueId = require('lodash/utility/uniqueId'),
has = require('lodash/object/has');
uniqueId = require('lodash/uniqueId'),
has = require('lodash/has');

// @ngInject
function queueManagerFactory($q, youtubeClient) {
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

var isUndefined = require('lodash/lang/isUndefined');
var isUndefined = require('lodash/isUndefined');

// @ngInject
function searchCtrlHelperFactory($window, $document, keyboardShortcutManager, searchInputsRegistry) {
Expand Down
File renamed without changes.
File renamed without changes
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

var pull = require('lodash/array/pull');
var pull = require('lodash/pull');

function interactiveChromesManagerFactory() {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';

var pull = require('lodash/array/pull'),
has = require('lodash/object/has');
var pull = require('lodash/pull'),
has = require('lodash/has');

// @ngInject
function pointerManagerFactory($timeout, $document) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
'use strict';

var angular = require('angular'),
defaults = require('lodash/object/defaults'),
has = require('lodash/object/has'),
pluck = require('lodash/collection/pluck');
defaults = require('lodash/defaults'),
has = require('lodash/has'),
map = require('lodash/map');

// @ngInject
function youtubeClientFactory($http, $q, configuration) {
Expand Down Expand Up @@ -52,7 +52,7 @@ function youtubeClientFactory($http, $q, configuration) {
throw new Error('YouTube API can not list more than ' + MAX_RESULTS_LIMIT + ' videos. Please reduce the videos ids list.');
}

var videosIds = pluck(videos, 'id');
var videosIds = map(videos, 'id');

// We have to use JSONP here
// - IE11 manages CORS request if originating page and requested resource have the same protocol
Expand Down
File renamed without changes.
Loading

0 comments on commit 94c6b34

Please sign in to comment.