Code cleanup

This commit is contained in:
Jonathan Cremin 2015-05-17 19:10:30 +01:00
parent a74ccfa575
commit be00516521
18 changed files with 209 additions and 202 deletions

99
app.js
View file

@ -1,92 +1,93 @@
"use strict";
var express = require('express');
var helmet = require('helmet');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var session = require('express-session');
var cookieParser = require('cookie-parser');
var flash = require('connect-flash');
var compress = require('compression');
var bodyParser = require('body-parser');
var pmongo = require('promised-mongo');
var express = require("express");
var helmet = require("helmet");
var path = require("path");
var favicon = require("serve-favicon");
var logger = require("morgan");
var session = require("express-session");
var cookieParser = require("cookie-parser");
var flash = require("connect-flash");
var compress = require("compression");
var bodyParser = require("body-parser");
var pmongo = require("promised-mongo");
var index = require('./routes/index');
var search = require('./routes/search');
var share = require('./routes/share');
var itunesProxy = require('./routes/itunes-proxy');
var index = require("./routes/index");
var search = require("./routes/search");
var share = require("./routes/share");
var itunesProxy = require("./routes/itunes-proxy");
var React = require('react');
var nodejsx = require('node-jsx').install({extension: '.jsx'});
var ErrorView = React.createFactory(require('./views/error.jsx'));
var React = require("react");
require("node-jsx").install({extension: ".jsx"});
var browserify = require('connect-browserify');
var ErrorView = React.createFactory(require("./views/error.jsx"));
var browserify = require("connect-browserify");
var app = express();
var development = process.env.NODE_ENV !== 'production';
var development = process.env.NODE_ENV !== "production";
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "ejs");
app.use(compress());
app.use(favicon(__dirname + '/public/images/favicon.png'));
app.use(favicon(path.join(__dirname, "/public/images/favicon.png")));
app.use(helmet());
app.use(logger('dev'));
app.use(logger("dev"));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(session({
secret: 'keyboard catz',
secret: "keyboard catz",
resave: false,
saveUninitialized: true
}));
app.use(flash());
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, "public")));
var dbUrl = process.env.MONGOHQ_URL || "mongodb://localhost/match-audio";
app.use(function(req, res, next) {
req.db = res.db = pmongo(dbUrl, ['matches']);
req.db = res.db = pmongo(dbUrl, ["matches"]);
next();
});
if (development) {
app.get('/javascript/bundle.js',
browserify('./views/app.jsx', {
app.get("/javascript/bundle.js",
browserify("./views/app.jsx", {
debug: true,
watch: true
}));
}
app.get('*', function(req,res,next) {
app.get("*", function(req, res, next) {
// force SSL
if (req.headers['cf-visitor'] && req.headers['cf-visitor'] != '{"scheme":"https"}') {
if (req.headers["cf-visitor"] && req.headers["cf-visitor"] !== "{\"scheme\":\"https\"}") {
return res.redirect("https://" + req.headers.host + req.url);
} else if (req.headers['cf-visitor']) {
} else if (req.headers["cf-visitor"]) {
req.userProtocol = "https";
} else {
req.userProtocol = "http";
}
// redirect www
if (req.headers.host.match(/^www/) !== null ) {
return res.redirect(req.userProtocol + '://' + req.headers.host.replace(/^www\./, '') + req.url);
return res.redirect(req.userProtocol + "://" + req.headers.host.replace(/^www\./, "") + req.url);
} else {
next();
}
});
app.get('/', index);
app.post('/search', search);
app.get('/:service/:type/:id.:format?', share);
app.get('/itunes/*', itunesProxy);
app.get('/recent', function(req, res, next) {
req.db.matches.find().sort({created_at:-1}).limit(6).toArray().then(function(docs){
app.get("/", index);
app.post("/search", search);
app.get("/:service/:type/:id.:format?", share);
app.get("/itunes/*", itunesProxy);
app.get("/recent", function(req, res, next) {
req.db.matches.find().sort({"created_at": -1}).limit(6).toArray().then(function(docs){
var recents = [];
docs.forEach(function(doc) {
recents.push(doc.services[doc._id.split("$$")[0]]);
recents.push(doc.services[doc._id.split("$$")[0]]); // eslint-disable-line no-underscore-dangle
});
res.json({recents:recents});
res.json({recents: recents});
}).catch(function (error) {
return next(error);
});
@ -94,7 +95,7 @@ app.get('/recent', function(req, res, next) {
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
var err = new Error("Not Found");
err.status = 404;
next(err);
});
@ -103,23 +104,23 @@ app.use(function(req, res, next) {
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
if (app.get("env") === "development") {
app.use(function(err, req, res) {
console.log(err.stack);
res.status(err.status || 500);
var content = React.renderToString(new ErrorView({status: err.status || 500, message: err.message, error: err}));
res.send('<!doctype html>\n' + content);
res.send("<!doctype html>\n" + content);
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
app.use(function(err, req, res) {
res.status(err.status || 500);
var content = React.renderToString(new ErrorView({status: err.status || 500, message: err.message, error: {status: err.status || 500}}));
res.send('<!doctype html>\n' + content);
res.send("<!doctype html>\n" + content);
});

View file

@ -1,6 +1,6 @@
#!/usr/bin/env node
"use strict";
var debug = require('debug')('unify.audio');
var debug = require('debug')('match.audio');
var app = require('../app');
app.set('port', process.env.PORT || 3000);

View file

@ -1,5 +1,5 @@
"use strict";
var path = require('path');
var path = require("path");
var services = [];
@ -17,7 +17,7 @@ module.exports = function(url) {
matchedService = service.match(url) ? service : null;
return matchedService;
});
if (matchedService) {
return matchedService.parseUrl(url).timeout(10000).then(function(result) {
return matchedService.lookupId(result.id, result.type).then(function(item) {

View file

@ -1,6 +1,5 @@
"use strict";
var path = require('path');
var Promise = require("bluebird");
var path = require("path");
module.exports = [];

View file

@ -1,8 +1,7 @@
"use strict";
var parse = require('url').parse;
var Promise = require('bluebird');
var request = require('superagent');
require('superagent-bluebird-promise');
var parse = require("url").parse;
var request = require("superagent");
require("superagent-bluebird-promise");
module.exports.id = "beats";
@ -29,10 +28,10 @@ module.exports.parseUrl = function(url) {
} else {
throw new Error("Url does not match");
}
}
};
module.exports.lookupId = function(id, type) {
if (type == "album") {
if (type === "album") {
return request.get(apiRoot + "/albums/" + id + "/images/default?size=large&client_id=" + credentials.key).redirects(0).promise().then(function(res) {
var artwork = {large: res.headers.location.replace("http:", "https:")};
return request.get(apiRoot + "/albums/" + id + "/images/default?client_id=" + credentials.key).redirects(0).promise().then(function(res) {
@ -59,7 +58,7 @@ module.exports.lookupId = function(id, type) {
});
});
});
} else if (type == "track") {
} else if (type === "track") {
return request.get(apiRoot + "/tracks/" + id + "?client_id=" + credentials.key).promise().then(function(res) {
if (!res.body.data) {
var error = new Error("Not Found");
@ -99,16 +98,20 @@ module.exports.lookupId = function(id, type) {
module.exports.search = function(data) {
var cleanParam = function(str) {
return str.replace(/[\:\?\&]+/, "");
}
};
var query, album;
var type = data.type;
if (type == "album") {
query = '"' + cleanParam(data.artist.name) + '" "' + cleanParam(data.name) + '"';
if (type === "album") {
query = "'" + cleanParam(data.artist.name) + "' '" + cleanParam(data.name) + "'";
album = data.name;
} else if (type == "track") {
query = '"' + cleanParam(data.artist.name) + '" "' + cleanParam(data.name) + '"';
album = data.album.name
} else if (type === "track") {
query = "'" + cleanParam(data.artist.name) + "' '" + cleanParam(data.name) + "'";
if (data.album) {
album = data.album.name;
} else {
album = "";
}
}
var path = "/search?q=" + encodeURIComponent(query) + "&type=" + type + "&client_id=" + credentials.key;
@ -118,20 +121,20 @@ module.exports.search = function(data) {
return {service: "beats"};
} else {
var found;
var choppedAlbum = data.type == "album" ? cleanParam(data.name) : cleanParam(data.album.name);
var choppedAlbum = data.type === "album" ? cleanParam(data.name) : cleanParam(data.album.name);
var choppedArtist = cleanParam(data.artist.name);
res.body.data.forEach(function(item) {
var matches = item.detail.match(/^[^\(\[]+/);
if(choppedArtist.indexOf(matches[0]) >= 0) {
found = item;
}
});
if (!found && !choppedAlbum.length) {
return module.exports.lookupId(res.body.data[0].id, type);
}
res.body.data.forEach(function(item) {
var matches = item.related.display.match(/^[^\(\[]+/);
if(choppedAlbum.indexOf(matches[0]) >= 0) {

View file

@ -1,5 +1,5 @@
"use strict";
var parse = require('url').parse;
var parse = require("url").parse;
module.exports.match = function(url) {
var parsed = parse(url);

View file

@ -1,18 +1,18 @@
"use strict";
var React = require('react');
var nodejsx = require('node-jsx').install({extension: '.jsx'});
var Router = require('react-router');
var routes = require('../views/app.jsx').routes;
var React = require("react");
var Router = require("react-router");
require("node-jsx").install({extension: ".jsx"});
var routes = require("../views/app.jsx").routes;
module.exports = function(req, res, next) {
req.db.matches.find().sort({created_at:-1}).limit(6).toArray().then(function(docs){
req.db.matches.find().sort({"created_at": -1}).limit(6).toArray().then(function(docs){
var recents = [];
docs.forEach(function(doc) {
var shares = Object.keys(doc.services).map(function (key) {return doc.services[key]});
var shares = Object.keys(doc.services).map(function (key) {return doc.services[key]; });
shares.some(function(item) {
if (item.service == doc._id.split("$$")[0]) {
if (item.service === doc._id.split("$$")[0]) { // eslint-disable-line no-underscore-dangle
recents.push(item);
return false;
}
@ -22,9 +22,9 @@ module.exports = function(req, res, next) {
Router.run(routes, req.url, function (Handler) {
var App = React.createFactory(Handler);
var content = React.renderToString(new App({recents: recents}));
res.send('<!doctype html>\n' + content.replace("</body></html>", "<script>var recents = " + JSON.stringify(recents) + "</script></body></html>"));
res.send("<!doctype html>\n" + content.replace("</body></html>", "<script>var recents = " + JSON.stringify(recents) + "</script></body></html>"));
});
}).catch(function(error) {
next(error);
});
}
};

View file

@ -1,6 +1,6 @@
"use strict";
var parse = require('url').parse;
var request = require('superagent');
var parse = require("url").parse;
var request = require("superagent");
module.exports = function(req, res) {
var url = "http://" + req.url.substr(8);

View file

@ -1,41 +1,40 @@
"use strict";
var parse = require('url').parse;
var path = require('path');
var lookup = require('../lib/lookup');
var services = require('../lib/services');
var parse = require("url").parse;
var lookup = require("../lib/lookup");
var services = require("../lib/services");
module.exports = function(req, res, next) {
module.exports = function(req, res) {
var url = parse(req.body.url);
if (!url.host) {
return res.json({error:{message:"You need to submit a url."}});
return res.json({error: {message: "You need to submit a url."}});
}
var promise = lookup(req.body.url);
if (!promise) {
return res.json({error: {message: "No supported music found at that link :("}});
}
promise.then(function(item) {
if (!item) {
return res.json({error: {message: "No supported music found at that link :("}});
}
item.matched_at = new Date();
item.matched_at = new Date(); // eslint-disable-line camelcase
var matches = {};
matches[item.service] = item;
services.forEach(function(service) {
if (service.id == item.service) {
if (service.id === item.service) {
return;
}
matches[service.id] = {service: service.id};
service.search(item).then(function(match) {
match.matched_at = new Date();
match.matched_at = new Date(); // eslint-disable-line camelcase
var update = {};
update["services." + match.service] = match;
req.db.matches.update({_id: item.service + "$$" + item.id}, {"$set": update});
});
});
return req.db.matches.save({_id: item.service + "$$" + item.id, created_at: new Date(), services:matches}).then(function() {
return req.db.matches.save({_id: item.service + "$$" + item.id, "created_at": new Date(), services: matches}).then(function() {
res.json(item);
});
}, function(error) {

View file

@ -1,25 +1,21 @@
"use strict";
var path = require('path');
var Promise = require('bluebird');
var util = require('util');
var browserify = require('connect-browserify');
var React = require('react');
var Router = require('react-router');
var nodejsx = require('node-jsx').install();
var routes = require('../views/app.jsx').routes;
var React = require("react");
var Router = require("react-router");
require("node-jsx").install();
var routes = require("../views/app.jsx").routes;
var services = require('../lib/services');
var services = require("../lib/services");
var formatAndSort = function(matches, serviceId) {
matches = Object.keys(matches).map(function (key) {return matches[key]});
matches = Object.keys(matches).map(function (key) {return matches[key]; });
matches.sort(function(a, b) {
return a.id && !b.id;
}).sort(function(a, b) {
return a.service != serviceId;
}).sort(function(a) {
return a.service !== serviceId;
});
return matches;
}
};
module.exports = function(req, res, next) {
var serviceId = req.params.service;
@ -28,50 +24,50 @@ module.exports = function(req, res, next) {
var matchedService;
services.some(function(service) {
matchedService = serviceId == service.id ? service : null;
matchedService = serviceId === service.id ? service : null;
return matchedService;
});
if (!matchedService || (type != "album" && type != "track")) {
if (!matchedService || (type !== "album" && type !== "track")) {
return next();
}
return req.db.matches.findOne({_id:serviceId + "$$" + itemId}).then(function(doc) {
return req.db.matches.findOne({_id: serviceId + "$$" + itemId}).then(function(doc) {
if (!doc) {
return matchedService.lookupId(itemId, type).then(function(item) {
var matches = {};
item.matched_at = new Date();
item.matched_at = new Date(); // eslint-disable-line camelcase
matches[item.service] = item;
services.forEach(function(service) {
if (service.id == item.service) {
if (service.id === item.service) {
return;
}
matches[service.id] = {service: service.id};
service.search(item).then(function(match) {
match.matched_at = new Date();
match.matched_at = new Date(); // eslint-disable-line camelcase
var update = {};
update["services." + match.service] = match;
req.db.matches.update({_id: item.service + "$$" + item.id}, {"$set": update});
});
});
return req.db.matches.save({_id: item.service + "$$" + item.id, created_at: new Date(), services:matches}).then(function() {
var shares = formatAndSort(matches, serviceId);
return req.db.matches.save({_id: item.service + "$$" + item.id, "created_at": new Date(), services: matches}).then(function() {
var newShares = formatAndSort(matches, serviceId);
Router.run(routes, req.url, function (Handler) {
var App = React.createFactory(Handler);
var content = React.renderToString(new App({shares: shares}));
res.send('<!doctype html>\n' + content.replace("</body></html>", "<script>var shares = " + JSON.stringify(shares) + "</script></body></html>"));
var content = React.renderToString(new App({shares: newShares}));
res.send("<!doctype html>\n" + content.replace("</body></html>", "<script>var shares = " + JSON.stringify(newShares) + "</script></body></html>"));
});
});
})
});
}
var shares = formatAndSort(doc.services, serviceId);
if (req.params.format == "json") {
return res.json({shares:shares});
if (req.params.format === "json") {
return res.json({shares: shares});
}
Router.run(routes, req.url, function (Handler) {
var App = React.createFactory(Handler);
var content = React.renderToString(new App({shares: shares}));
res.send('<!doctype html>\n' + content.replace("</body></html>", "<script>var shares = " + JSON.stringify(shares) + "</script></body></html>"));
res.send("<!doctype html>\n" + content.replace("</body></html>", "<script>var shares = " + JSON.stringify(shares) + "</script></body></html>"));
});
}).catch(function (error) {
return next(error);

11
views/.eslintrc Normal file
View file

@ -0,0 +1,11 @@
{
"ecmaFeatures": {
"jsx": true
},
"plugins": [
"react"
],
"env": {
"browser": true
}
}

View file

@ -1,23 +1,19 @@
'use strict';
"use strict";
var request = require('superagent');
var React = require('react');
var Router = require('react-router');
var Route = require('react-router').Route;
var DefaultRoute = require('react-router').DefaultRoute;
var NotFoundRoute = require('react-router').NotFoundRoute;
var RouteHandler = require('react-router').RouteHandler;
var Home = require('./home.jsx');
var Share = require('./share.jsx');
var Error = require('./error.jsx');
var Head = require('./head.jsx');
var ga = require('react-google-analytics');
var React = require("react");
var Router = require("react-router");
var Route = require("react-router").Route;
var DefaultRoute = require("react-router").DefaultRoute;
var NotFoundRoute = require("react-router").NotFoundRoute;
var RouteHandler = require("react-router").RouteHandler;
var Home = require("./home.jsx");
var Share = require("./share.jsx");
var Head = require("./head.jsx");
var ga = require("react-google-analytics");
var GAInitiailizer = ga.Initializer;
var App = React.createClass({
render: function () {
return (
<html>
<Head {...this.props} />
@ -47,16 +43,16 @@ var routes = (
module.exports.routes = routes;
if (typeof window !== 'undefined') {
if (typeof window !== "undefined") {
window.onload = function() {
Router.run(routes, Router.HistoryLocation, function (Handler) {
if (typeof recents !== "undefined") {
React.render(<Handler recents={recents} />, document);
if (typeof window.recents !== "undefined") {
React.render(<Handler recents={window.recents} />, document);
} else if (typeof shares !== "undefined") {
React.render(<Handler shares={shares} />, document);
React.render(<Handler shares={window.shares} />, document);
}
});
ga('create', 'UA-66209-8', 'auto');
ga('send', 'pageview');
}
}
ga("create", "UA-66209-8", "auto");
ga("send", "pageview");
};
}

View file

@ -1,8 +1,8 @@
'use strict';
"use strict";
var React = require('react');
var Head = require('./head.jsx');
var Foot = require('./foot.jsx');
var React = require("react");
var Head = require("./head.jsx");
var Foot = require("./foot.jsx");
module.exports = React.createClass({

View file

@ -1,6 +1,6 @@
'use strict';
"use strict";
var React = require('react');
var React = require("react");
module.exports = React.createClass({

View file

@ -1,6 +1,6 @@
'use strict';
"use strict";
var React = require('react');
var React = require("react");
module.exports = React.createClass({
@ -9,7 +9,7 @@ module.exports = React.createClass({
<footer>
<div className="container">
<div className="row">
<div className={this.props.page == "home" || this.props.page == "error" ? "col-md-6 col-md-offset-3" : "col-md-12"}>
<div className={this.props.page === "home" || this.props.page === "error" ? "col-md-6 col-md-offset-3" : "col-md-12"}>
<a href="https://twitter.com/MatchAudio">Tweet</a> or <a href="https://github.com/kudos/match.audio">Fork</a>. A work in progress by <a href="http://crem.in">this guy</a>.
</div>
</div>

View file

@ -1,12 +1,14 @@
'use strict';
"use strict";
var React = require('react');
var Router = require('react-router');
var React = require("react");
var Router = require("react-router");
module.exports = React.createClass({
mixins: [ Router.State ],
mixins: [ Router.State ],
contextTypes: {
router: React.PropTypes.func.isRequired
},
render: function() {
var image = this.props.shares ? this.props.shares[0].artwork.large : "https://match.audio/images/logo-512.png";
var title = this.props.shares ? this.props.shares[0].name + " by " + this.props.shares[0].artist.name : "Match Audio";
@ -15,7 +17,7 @@ module.exports = React.createClass({
<head>
<meta charSet="utf-8" />
<meta httpEquiv="X-UA-Compatible" content="IE=edge" />
<title>{this.props.shares ? "Listen to " + this.props.shares[0].name + " by " + this.props.shares[0].artist.name + " on Match Audio": "Match Audio"}</title>
<title>{this.props.shares ? "Listen to " + this.props.shares[0].name + " by " + this.props.shares[0].artist.name + " on Match Audio" : "Match Audio"}</title>
<meta name="description" content="Match Audio matches album and track links from Youtube, Rdio, Spotify, Deezer, Google Music, Xbox Music, Beats Music, and iTunes and give you back one link with matches we find on all of them." />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#FE4365" />
@ -27,10 +29,10 @@ module.exports = React.createClass({
<meta property="og:url" content={shareUrl} />
<link rel="shortcut icon" href="/images/favicon.png" />
<link rel="icon" sizes="512x512" href="/images/logo-128.png" />
<link href='//fonts.googleapis.com/css?family=Open+Sans:400,300,700' rel='stylesheet' type='text/css' />
<link href="//fonts.googleapis.com/css?family=Open+Sans:400,300,700" rel="stylesheet" type="text/css" />
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
<link rel="stylesheet" href="/stylesheets/style.css" />
</head>
);
}
});
});

View file

@ -1,11 +1,11 @@
'use strict';
"use strict";
var React = require('react');
var request = require('superagent');
var Router = require('react-router');
var Link = require('react-router').Link;
var Faq = require('./faq.jsx');
var Foot = require('./foot.jsx');
var React = require("react");
var request = require("superagent");
var Router = require("react-router");
var Link = require("react-router").Link;
var Faq = require("./faq.jsx");
var Foot = require("./foot.jsx");
var Recent = React.createClass({
@ -33,7 +33,7 @@ var RecentItem = React.createClass({
return (
<div className="col-sm-4 col-xs-6">
<Link to="share" params={this.props.item}>
<div className={this.props.item.service == "youtube" ? "artwork-youtube artwork" : "artwork"} style={{backgroundImage: "url("+this.props.item.artwork.small+")"}}></div>
<div className={this.props.item.service === "youtube" ? "artwork-youtube artwork" : "artwork"} style={{backgroundImage: "url(" + this.props.item.artwork.small + ")"}}></div>
</Link>
</div>
);
@ -65,7 +65,7 @@ var SearchForm = React.createClass({
});
return;
}
request.post('/search').send({url:url}).end(function(res) {
request.post("/search").send({url: url}).end(function(res) {
that.setState({
submitting: false
});
@ -115,10 +115,10 @@ module.exports = React.createClass({
recents: []
};
},
componentDidMount: function () {
if (!this.props.recents) {
request.get('/recent').set('Accept', 'application/json').end(function(res) {
request.get("/recent").set("Accept", "application/json").end(function(res) {
this.setState({
recents: res.body.recents
});
@ -142,7 +142,7 @@ module.exports = React.createClass({
<div className="row blurb">
<div className="col-md-6 col-md-offset-3">
<p>Match Audio makes sharing from music services better.
What happens when you share your favourite song on Spotify with a friend, but they don't use Spotify?
What happens when you share your favourite song on Spotify with a friend, but they don"t use Spotify?
</p><p>We match album and track links from Youtube, Rdio, Spotify, Deezer, Google Music, Xbox Music, Beats Music, and iTunes and give you back one link with matches we find on all of them.
</p>
</div>

View file

@ -1,10 +1,10 @@
'use strict';
"use strict";
var React = require('react');
var request = require('superagent');
var Router = require('react-router');
var Link = require('react-router').Link;
var Foot = require('./foot.jsx');
var React = require("react");
var request = require("superagent");
var Router = require("react-router");
var Link = require("react-router").Link;
var Foot = require("./foot.jsx");
var MusicItem = React.createClass({
@ -13,7 +13,7 @@ var MusicItem = React.createClass({
return (
<div className="col-md-3 col-xs-6">
<div className="service">
<div className="artwork" style={{backgroundImage: "url("+this.props.items[0].artwork.small+")"}}>
<div className="artwork" style={{backgroundImage: "url(" + this.props.items[0].artwork.small + ")"}}>
</div>
<div className="loading-wrap">
<img src="/images/eq.svg" className="loading" />
@ -28,7 +28,7 @@ var MusicItem = React.createClass({
return (
<div className="col-md-3 col-xs-6">
<div className="service">
<div className="artwork not-found" style={{backgroundImage: "url("+this.props.items[0].artwork.small+")"}}></div>
<div className="artwork not-found" style={{backgroundImage: "url(" + this.props.items[0].artwork.small + ")"}}></div>
<div className="no-match">
No Match
</div>
@ -41,13 +41,13 @@ var MusicItem = React.createClass({
} else {
return (
<div className="col-md-3 col-xs-6">
<div className={"service" + (this.props.inc == 0 ? " source-service" : "")}>
<div className="matching-from hidden-xs">{this.props.inc == 0 ? "Found matches using this link": ""}</div>
<div className={"service" + (this.props.inc === 0 ? " source-service" : "")}>
<div className="matching-from hidden-xs">{this.props.inc === 0 ? "Found matches using this link" : ""}</div>
<a href={this.props.item.streamUrl || this.props.item.purchaseUrl}>
<div className={this.props.item.service == "youtube" ? "artwork-youtube artwork" : "artwork"} style={{backgroundImage: "url("+this.props.item.artwork.small+")"}}>
<div className={this.props.item.service === "youtube" ? "artwork-youtube artwork" : "artwork"} style={{backgroundImage: "url(" + this.props.item.artwork.small + ")"}}>
</div>
<div className={this.props.item.service == "youtube" && this.props.inc > 0 ? "youtube" : ""}>
{this.props.item.service == "youtube" && this.props.inc > 0 ? this.props.item.name : ""}
<div className={this.props.item.service === "youtube" && this.props.inc > 0 ? "youtube" : ""}>
{this.props.item.service === "youtube" && this.props.inc > 0 ? this.props.item.name : ""}
</div>
</a>
<div className="service-link">
@ -68,7 +68,7 @@ module.exports = React.createClass({
mixins: [ Router.State ],
getInitialState: function () {
if (this.props.shares && this.props.shares[0].id == this.getParams().id) {
if (this.props.shares && this.props.shares[0].id === this.getParams().id) {
return {
name: this.props.shares[0].name,
artist: this.props.shares[0].artist.name,
@ -92,13 +92,13 @@ module.exports = React.createClass({
componentDidMount: function () {
var complete = this.state.shares.length > 0;
this.state.shares.forEach(function(share) {
if (typeof share.matched_at === "undefined") {
complete = false;
}
});
var getShares = function() {
request.get(this.getPathname() + ".json").end(function(res) {
var shares = res.body.shares;
@ -108,11 +108,11 @@ module.exports = React.createClass({
complete = false;
}
});
if (complete) {
clearInterval(this.state.interval);
}
if (shares.length) {
this.setState({
name: shares[0].name,
@ -122,8 +122,8 @@ module.exports = React.createClass({
});
}
}.bind(this));
}.bind(this)
}.bind(this);
if (!this.state.shares.length) {
getShares();
}
@ -133,23 +133,23 @@ module.exports = React.createClass({
if (!complete) {
getShares();
}
}.bind(this), 2000);
}, 2000);
// Some hacks to pop open the Twitter/Facebook/Google Plus sharing dialogs without using their code.
Array.prototype.forEach.call(document.querySelectorAll(".share-dialog"), function(dialog){
dialog.addEventListener("click", function(event) {
event.preventDefault();
var w = 845;
var h = 670;
var dualScreenLeft = window.screenLeft != undefined ? window.screenLeft : screen.left;
var dualScreenTop = window.screenTop != undefined ? window.screenTop : screen.top;
var dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left;
var dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top;
var width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width;
var height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height;
var left = ((width / 2) - (w / 2)) + dualScreenLeft;
var top = ((height / 2) - (h / 2)) + dualScreenTop;
var newWindow = window.open(dialog.href, "Share Music", 'scrollbars=yes, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left);
var newWindow = window.open(dialog.href, "Share Music", "scrollbars=yes, width=" + w + ", height=" + h + ", top=" + top + ", left=" + left);
if (window.focus) {
newWindow.focus();
}