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){