From 874c3c162ce6627fccff55fa6e72ccded1e162cf Mon Sep 17 00:00:00 2001 From: Jonathan Cremin Date: Tue, 23 Dec 2014 00:35:17 +0000 Subject: [PATCH] Load matches after page load --- package.json | 2 +- public/images/grid.svg | 56 ++++++++++++++++++++++++++++ public/stylesheets/style.css | 8 +++- routes/search.js | 9 ++--- routes/share.js | 4 -- views/home.jsx | 15 ++++++-- views/share.jsx | 71 +++++++++++++++++++++++++++++++----- 7 files changed, 140 insertions(+), 25 deletions(-) create mode 100644 public/images/grid.svg diff --git a/package.json b/package.json index d4f8c1e..4251e87 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "body-parser": "~1.8.1", "compression": "^1.2.2", "connect-flash": "^0.1.1", + "connect-browserify": "^3.2.1", "cookie-parser": "~1.3.3", "crypto-js": "^3.1.2-5", "debug": "~2.0.0", @@ -48,7 +49,6 @@ }, "devDependencies": { "browserify": "^7.0.0", - "connect-browserify": "^3.2.1", "should": "^4.3.0", "mocha": "^2.0.1", "envify": "^3.2.0", diff --git a/public/images/grid.svg b/public/images/grid.svg new file mode 100644 index 0000000..140cb89 --- /dev/null +++ b/public/images/grid.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css index 24821f7..9af324c 100644 --- a/public/stylesheets/style.css +++ b/public/stylesheets/style.css @@ -138,7 +138,13 @@ h3 { margin-bottom: 10px; } .not-found { - opacity: 0.3; + opacity: 0.5; +} +.loading { + position: absolute; + top: 33%; + left: 33%; + width: 33%; } .service-link { text-align: center; diff --git a/routes/search.js b/routes/search.js index da19e5e..61b977b 100644 --- a/routes/search.js +++ b/routes/search.js @@ -16,8 +16,7 @@ module.exports = function(req, res, next) { var searching = false; if (!url.host) { - req.flash('search-error', 'Paste a music link above to find and share the matches'); - res.redirect('/'); + res.json({error:{message:"You need to submit a url."}}); } else { var items = {}; for (var id in services) { @@ -34,16 +33,14 @@ module.exports = function(req, res, next) { services[id].lookupId(result.id, result.type).then(function(item) { items[id] = item; req.db.matches.save({_id:id + "$$" + result.id, created_at: new Date(), services:items}).then(function() { - setTimeout(function() { - res.json(item); - }, 1000) + res.json(item); }); }); } }, function(error) { if (error.code == "ETIMEDOUT") { error = new Error("Error talking to music service"); - error.status = "502"; + error.status = 502; next(error); } else if (!error || !error.status) { error = new Error("An unexpected error happenend"); diff --git a/routes/share.js b/routes/share.js index 8b4ac6b..24b60db 100644 --- a/routes/share.js +++ b/routes/share.js @@ -60,10 +60,6 @@ module.exports = function(req, res, next) { }); shares.sort(function(a, b) { - return !a.id || !b.id; - }).sort(function(a, b) { - return !a.streamUrl || b.streamUrl; - }).sort(function(a, b) { return a.type == "video" && b.type != "video"; }); diff --git a/views/home.jsx b/views/home.jsx index e91bef9..e36675c 100644 --- a/views/home.jsx +++ b/views/home.jsx @@ -47,8 +47,7 @@ var SearchForm = React.createClass({ return; } request.post('/search').send({url:url}).end(function(res) { - console.log(res) - that.transitionTo("/" + res.body.service + "/" + res.body.type + "/" + res.body.id); + that.transitionTo("share", res.body); }); }, @@ -69,8 +68,16 @@ var SearchForm = React.createClass({ module.exports = React.createClass({ getInitialState: function () { + // Use this only on first page load, refresh whenever we navigate back. + if (this.props.recents) { + var recents = this.props.recents; + delete this.props.recents; + return { + recents: recents + }; + } return { - recents: this.props.recents + recents: [] }; }, @@ -104,7 +111,7 @@ module.exports = React.createClass({

- + diff --git a/views/share.jsx b/views/share.jsx index 11a5cc9..0100582 100644 --- a/views/share.jsx +++ b/views/share.jsx @@ -9,11 +9,22 @@ var Foot = require('./foot.jsx'); var MusicItem = React.createClass({ render: function() { - if (!this.props.item.name) { + if (typeof this.props.item.id === "undefined") { + return ( +
+
+ + +
+ +
+
+
+ ); + } else if (this.props.item.id === null) { return (
-
@@ -24,8 +35,8 @@ var MusicItem = React.createClass({ } else { return (
-
-
+
+
{this.props.inc == 0 ? "Found matches using this link": ""}
@@ -67,24 +78,66 @@ module.exports = React.createClass({ mixins: [ Router.State ], getInitialState: function () { + if (this.props.shares && this.props.shares[0].id == this.getParams().id) { + return { + name: this.props.shares ? this.props.shares[0].name : "", + artist: this.props.shares ? this.props.shares[0].artist.name : "", + shares: this.props.shares || [] + }; + } return { - name: this.props.shares[0].name || "", - artist: this.props.shares[0].artist.name || "", - shares: this.props.shares || [] + name: "", + artist: "", + shares: [] }; }, + componentWillUnmount: function() { + if (this.state.interval) { + clearInterval(this.state.interval); + } + }, + componentDidMount: function () { - if (!this.props.shares) { + var complete = this.state.shares.length > 0; + + this.state.shares.forEach(function(share) { + if (typeof share.id === "undefined") { + complete = false; + } + }); + + var getShares = function() { request.get(this.getPathname()).set('Accept', 'application/json').end(function(res) { var shares = res.body.shares; + complete = true; + shares.forEach(function(share) { + if (typeof share.id === "undefined") { + complete = false; + } + }); + + if (complete) { + clearInterval(this.state.interval); + } + this.setState({ name: shares[0].name, artist: shares[0].artist.name, shares: shares }); - }.bind(this)) + }.bind(this)); + }.bind(this) + + if (!this.state.shares.length) { + getShares(); } + + this.state.interval = setInterval(function() { + if (!complete) { + getShares(); + } + }.bind(this), 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){