mirror of
https://github.com/moparisthebest/kaiwa
synced 2024-12-23 16:18:48 -05:00
Add support for oembeds
This commit is contained in:
parent
e09290e623
commit
9369b00665
55
clientapp/helpers/embedIt.js
Normal file
55
clientapp/helpers/embedIt.js
Normal file
@ -0,0 +1,55 @@
|
||||
/*global $, app*/
|
||||
var _ = require('underscore');
|
||||
var async = require('async');
|
||||
var templates = require('../templates');
|
||||
|
||||
var embedQueue = async.cargo(function (links, cb) {
|
||||
var urls = [];
|
||||
_.each(links, function (link) {
|
||||
urls.push({
|
||||
value: link.href,
|
||||
el: link
|
||||
});
|
||||
});
|
||||
$.ajax({
|
||||
// We have to massage the data into the URL ourselves because
|
||||
// jQuery won't let us have unencoded commas between encoded URLs
|
||||
url: '/oembed?' + $.param({
|
||||
maxwidth: 500
|
||||
}) + '&urls=' + _.map(urls, function (item) { return encodeURIComponent(item.value); }).join(','),
|
||||
dataType: 'jsonp',
|
||||
success: function (data) {
|
||||
var maxWidth = 500;
|
||||
data = _.filter(data, function (item, i) {
|
||||
item.original = urls[i].value;
|
||||
item.el = urls[i].el;
|
||||
return item.type === 'video' || item.type === 'photo';
|
||||
});
|
||||
data.forEach(function (item) {
|
||||
if (item.width && item.height && item.width > maxWidth) {
|
||||
var ratio = maxWidth / item.width;
|
||||
item.width = maxWidth;
|
||||
item.height = parseInt(item.height * ratio, 10);
|
||||
}
|
||||
$(item.el).replaceWith(templates.includes.embeds(item));
|
||||
});
|
||||
}
|
||||
});
|
||||
}, 10);
|
||||
|
||||
module.exports = function ($html, cb) {
|
||||
cb = cb || function () {};
|
||||
|
||||
//if (!app.settings.chatEmbeds) return cb();
|
||||
if (!$html.jquery) cb('$html is not a jQuery collection.');
|
||||
var $links;
|
||||
var batches = [];
|
||||
var allUrls = [];
|
||||
var selector = 'a[target="_blank"]:not(".original")';
|
||||
$links = $html.find(selector);
|
||||
if (!$links.length) $links = $html.filter(selector);
|
||||
|
||||
$links.each(function (idx, link) {
|
||||
embedQueue.push(link);
|
||||
});
|
||||
};
|
8759
clientapp/libraries/jquery.js
vendored
8759
clientapp/libraries/jquery.js
vendored
File diff suppressed because one or more lines are too long
@ -7,6 +7,7 @@ var BasePage = require('./base');
|
||||
var templates = require('../templates');
|
||||
var Message = require('../views/message');
|
||||
var MessageModel = require('../models/message');
|
||||
var embedIt = require('../helpers/embedIt');
|
||||
var attachMediaStream = require('attachmediastream');
|
||||
|
||||
|
||||
@ -210,10 +211,12 @@ module.exports = BasePage.extend({
|
||||
last = this.$messageList.find('li').last();
|
||||
last.find('.messageWrapper').append(newEl);
|
||||
last.addClass('chatGroup');
|
||||
this.staydown.checkdown();
|
||||
} else {
|
||||
newEl = $(model.templateHtml);
|
||||
this.staydown.append(newEl[0]);
|
||||
}
|
||||
embedIt(newEl);
|
||||
this.lastModel = model;
|
||||
},
|
||||
handleEndClick: function (e) {
|
||||
|
@ -8,6 +8,7 @@ var templates = require('../templates');
|
||||
var MUCRosterItem = require('../views/mucRosterItem');
|
||||
var Message = require('../views/mucMessage');
|
||||
var MessageModel = require('../models/message');
|
||||
var embedIt = require('../helpers/embedIt');
|
||||
|
||||
|
||||
module.exports = BasePage.extend({
|
||||
@ -213,10 +214,12 @@ module.exports = BasePage.extend({
|
||||
last = this.$messageList.find('li').last();
|
||||
last.find('.messageWrapper').append(newEl);
|
||||
last.addClass('chatGroup');
|
||||
this.staydown.checkdown();
|
||||
} else {
|
||||
newEl = $(model.templateHtml);
|
||||
this.staydown.append(newEl[0]);
|
||||
}
|
||||
embedIt(newEl);
|
||||
this.lastModel = model;
|
||||
},
|
||||
refreshModel: function (model) {
|
||||
|
@ -83,6 +83,69 @@ exports.includes.contactRequest = function anonymous(locals) {
|
||||
return buf.join("");
|
||||
};
|
||||
|
||||
// embeds.jade compiled template
|
||||
exports.includes.embeds = function anonymous(locals) {
|
||||
var buf = [];
|
||||
with (locals || {}) {
|
||||
if (locals.type === "photo") {
|
||||
buf.push("<a" + jade.attrs({
|
||||
href: locals.original,
|
||||
target: "_blank",
|
||||
"class": "embed" + " " + "photo"
|
||||
}, {
|
||||
href: true,
|
||||
target: true
|
||||
}) + "><img" + jade.attrs({
|
||||
width: locals.width,
|
||||
height: locals.height,
|
||||
src: locals.url,
|
||||
alt: locals.title,
|
||||
"class": "embedded"
|
||||
}, {
|
||||
width: true,
|
||||
height: true,
|
||||
src: true,
|
||||
alt: true
|
||||
}) + "/></a><br/><a" + jade.attrs({
|
||||
href: locals.original,
|
||||
target: "_blank",
|
||||
"class": "embed" + " " + "original"
|
||||
}, {
|
||||
href: true,
|
||||
target: true
|
||||
}) + ">" + jade.escape(null == (jade.interp = locals.original) ? "" : jade.interp) + "</a>");
|
||||
} else if (locals.type === "video" && locals.thumbnail_url) {
|
||||
buf.push("<a" + jade.attrs({
|
||||
href: locals.original,
|
||||
target: "_blank",
|
||||
"class": "embed" + " " + "preview"
|
||||
}, {
|
||||
href: true,
|
||||
target: true
|
||||
}) + "><img" + jade.attrs({
|
||||
width: locals.width,
|
||||
height: locals.height,
|
||||
src: locals.thumbnail_url,
|
||||
alt: locals.title,
|
||||
"class": "embedded"
|
||||
}, {
|
||||
width: true,
|
||||
height: true,
|
||||
src: true,
|
||||
alt: true
|
||||
}) + "/></a><br/><a" + jade.attrs({
|
||||
href: locals.original,
|
||||
target: "_blank",
|
||||
"class": "embed" + " " + "original"
|
||||
}, {
|
||||
href: true,
|
||||
target: true
|
||||
}) + ">" + jade.escape(null == (jade.interp = locals.original) ? "" : jade.interp) + "</a>");
|
||||
}
|
||||
}
|
||||
return buf.join("");
|
||||
};
|
||||
|
||||
// message.jade compiled template
|
||||
exports.includes.message = function anonymous(locals) {
|
||||
var buf = [];
|
||||
|
10
clientapp/templates/includes/embeds.jade
Normal file
10
clientapp/templates/includes/embeds.jade
Normal file
@ -0,0 +1,10 @@
|
||||
- if (locals.type === 'photo')
|
||||
a.embed.photo(href=locals.original, target="_blank")
|
||||
img.embedded(width=locals.width, height=locals.height, src=locals.url, alt=locals.title)
|
||||
br
|
||||
a.embed.original(href=locals.original, target="_blank")= locals.original
|
||||
- else if (locals.type === 'video' && locals.thumbnail_url)
|
||||
a.embed.preview(href=locals.original, target="_blank")
|
||||
img.embedded(width=locals.width, height=locals.height, src=locals.thumbnail_url, alt=locals.title);
|
||||
br
|
||||
a.embed.original(href=locals.original, target="_blank")= locals.original
|
@ -16,6 +16,7 @@ module.exports = HumanView.extend({
|
||||
},
|
||||
events: {
|
||||
'click a[href]': 'handleLinkClick',
|
||||
'click a.embed img': 'handleEmbedClick',
|
||||
'click .reconnect': 'handleReconnect',
|
||||
'click .logout': 'handleLogout',
|
||||
'blur #me .status': 'handleStatusChange'
|
||||
@ -57,6 +58,12 @@ module.exports = HumanView.extend({
|
||||
return false;
|
||||
}
|
||||
},
|
||||
handleEmbedClick: function (e) {
|
||||
if (e.shiftKey) {
|
||||
e.preventDefault();
|
||||
$(e.target).hide();
|
||||
}
|
||||
},
|
||||
handleTitle: function (e) {
|
||||
document.title = app.state.title;
|
||||
app.desktop.updateBadge(app.state.badge);
|
||||
|
@ -6,6 +6,9 @@
|
||||
"key": "./fakekeys/privatekey.pem",
|
||||
"cert": "./fakekeys/certificate.pem"
|
||||
},
|
||||
"embedly": {
|
||||
"key": ""
|
||||
},
|
||||
"session": {
|
||||
"secret": "shhhhhh don't tell anyone ok?"
|
||||
}
|
||||
|
29
package.json
29
package.json
@ -7,29 +7,30 @@
|
||||
"url": "git@github.com:andyet/otalk.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"bows": "0.3.0",
|
||||
"async": "0.2.9",
|
||||
"attachmediastream": "1.0.1",
|
||||
"backbone": "1.0.0",
|
||||
"bows": "0.3.0",
|
||||
"browserify": "2.25.1",
|
||||
"crypto-browserify": "1.0.3",
|
||||
"express": "3.3.7",
|
||||
"getconfig": "0.0.5",
|
||||
"jade": "0.35.0",
|
||||
"moonboots": "1.0.0",
|
||||
"getusermedia": "0.2.1",
|
||||
"helmet": "0.1.0",
|
||||
"node-uuid": "1.4.1",
|
||||
"semi-static": "0.0.4",
|
||||
"sound-effect-manager": "0.0.5",
|
||||
"human-model": "1.4.0",
|
||||
"human-view": "1.2.0",
|
||||
"jade": "0.35.0",
|
||||
"moonboots": "1.0.0",
|
||||
"node-uuid": "1.4.1",
|
||||
"notify.js": "0.0.3",
|
||||
"oembed": "0.1.0",
|
||||
"semi-static": "0.0.4",
|
||||
"sound-effect-manager": "0.0.5",
|
||||
"stanza.io": "2.10.0",
|
||||
"staydown": "legastero/staydown",
|
||||
"templatizer": "0.1.2",
|
||||
"underscore": "1.5.1",
|
||||
"stanza.io": "2.10.0",
|
||||
"notify.js": "0.0.3",
|
||||
"wildemitter": "0.0.5",
|
||||
"attachmediastream": "1.0.1",
|
||||
"getusermedia": "0.2.1",
|
||||
"crypto-browserify": "1.0.3",
|
||||
"browserify": "2.25.1",
|
||||
"staydown": "1.0.2"
|
||||
"wildemitter": "0.0.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"precommit-hook": "0.3.6"
|
||||
|
@ -1112,6 +1112,16 @@ button.secondary:hover:not(:disabled) {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
}
|
||||
.messages li p a {
|
||||
display: inline;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
}
|
||||
.messages li p img {
|
||||
margin: 5px 0;
|
||||
border-radius: 5px;
|
||||
box-shadow: rgba(0,0,0,0.25) 0 2px 3px;
|
||||
}
|
||||
.messages .sender {
|
||||
display: table-cell;
|
||||
font-size: 12px;
|
||||
|
@ -219,6 +219,16 @@
|
||||
position: absolute
|
||||
width: 1px
|
||||
|
||||
p a
|
||||
display: inline
|
||||
word-wrap: break-word
|
||||
word-break: break-all
|
||||
|
||||
p img
|
||||
margin: 5px 0
|
||||
border-radius: 5px
|
||||
box-shadow: rgba(0, 0, 0, .25) 0 2px 3px
|
||||
|
||||
.sender
|
||||
display: table-cell
|
||||
font-size: 12px
|
||||
|
@ -1,5 +1,5 @@
|
||||
CACHE MANIFEST
|
||||
# 0.0.1 1388608475000
|
||||
# 0.0.1 1388621917445
|
||||
|
||||
CACHE:
|
||||
/app.js
|
||||
|
52
server.js
52
server.js
@ -5,6 +5,8 @@ var helmet = require('helmet');
|
||||
var Moonboots = require('moonboots');
|
||||
var config = require('getconfig');
|
||||
var templatizer = require('templatizer');
|
||||
var oembed = require('oembed');
|
||||
var async = require('async');
|
||||
|
||||
|
||||
var app = express();
|
||||
@ -17,13 +19,15 @@ if (!config.isDev) {
|
||||
app.use(helmet.iexss());
|
||||
app.use(helmet.contentTypeOptions());
|
||||
|
||||
oembed.EMBEDLY_URL = config.embedly.url;
|
||||
oembed.EMBEDLY_KEY = config.embedly.key;
|
||||
|
||||
var clientApp = new Moonboots({
|
||||
main: __dirname + '/clientapp/app.js',
|
||||
templateFile: __dirname + '/clientapp/templates/main.html',
|
||||
developmentMode: config.isDev,
|
||||
libraries: [
|
||||
__dirname + '/clientapp/libraries/zepto.js',
|
||||
__dirname + '/clientapp/libraries/jquery.js',
|
||||
__dirname + '/clientapp/libraries/ui.js',
|
||||
__dirname + '/clientapp/libraries/resampler.js',
|
||||
__dirname + '/clientapp/libraries/IndexedDBShim.min.js'
|
||||
@ -86,6 +90,52 @@ app.get('/manifest.cache', function (req, res, next) {
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/oembed', function (req, res) {
|
||||
var callback = req.query.callback;
|
||||
if (req.query.url) {
|
||||
oembed.fetch(req.query.url, req.query, function (err, result) {
|
||||
if (err || !result) {
|
||||
return res.status(500).send();
|
||||
}
|
||||
res.status(200);
|
||||
res.set('Content-Type', oembed.MIME_OEMBED_JSON);
|
||||
if (callback) {
|
||||
res.send(callback + '(' + JSON.stringify(result) + ')');
|
||||
} else {
|
||||
res.send(JSON.stringify(result));
|
||||
}
|
||||
});
|
||||
} else if (req.query.urls) {
|
||||
var cache = {};
|
||||
var urls = req.query.urls.split(',');
|
||||
delete req.query.urls;
|
||||
async.forEach(urls, function (url, cb) {
|
||||
oembed.fetch(url, req.query, function (err, result) {
|
||||
if (err || !result) {
|
||||
result = {type: 'error'};
|
||||
}
|
||||
cache[url] = result;
|
||||
cb();
|
||||
});
|
||||
}, function () {
|
||||
res.status(200);
|
||||
var results = [];
|
||||
urls.forEach(function (url) {
|
||||
results.push(cache[url]);
|
||||
});
|
||||
if (callback) {
|
||||
res.set('Content-Type', 'application/javascript');
|
||||
res.send(callback + '(' + JSON.stringify(results) + ')');
|
||||
} else {
|
||||
res.set('Content-Type', 'application/json');
|
||||
res.send(JSON.stringify(results));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
res.status(400).send();
|
||||
}
|
||||
});
|
||||
|
||||
// serves app on every other url
|
||||
app.get('*', clientApp.html());
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user