diff options
| author | Jules Laplace <jules@okfoc.us> | 2014-06-12 18:01:20 -0400 |
|---|---|---|
| committer | Jules Laplace <jules@okfoc.us> | 2014-06-12 18:01:20 -0400 |
| commit | f9a05332e51b586b42cffcf144dae6f4b3abe436 (patch) | |
| tree | ed9f30f241bbdca6c6c3717afd76d1356179f257 | |
| parent | e37702d371b459847a43f7c6f953dff31684d823 (diff) | |
client side of uploading process
| -rw-r--r-- | public/assets/img/loader.gif | bin | 0 -> 529 bytes | |||
| -rw-r--r-- | public/assets/javascripts/ui/editor/MediaUpload.js | 78 | ||||
| -rw-r--r-- | public/assets/javascripts/ui/editor/MediaViewer.js | 3 | ||||
| -rw-r--r-- | public/assets/javascripts/ui/lib/AlertModal.js | 1 | ||||
| -rw-r--r-- | public/assets/javascripts/ui/lib/Parser.js | 96 | ||||
| -rwxr-xr-x | public/assets/stylesheets/app.css | 12 | ||||
| -rw-r--r-- | server/lib/api/media.js | 46 | ||||
| -rw-r--r-- | server/lib/schemas/Media.js | 26 | ||||
| -rw-r--r-- | views/controls/editor/media-drawer.ejs | 6 | ||||
| -rw-r--r-- | views/partials/scripts.ejs | 1 |
10 files changed, 259 insertions, 10 deletions
diff --git a/public/assets/img/loader.gif b/public/assets/img/loader.gif Binary files differnew file mode 100644 index 0000000..c14d375 --- /dev/null +++ b/public/assets/img/loader.gif diff --git a/public/assets/javascripts/ui/editor/MediaUpload.js b/public/assets/javascripts/ui/editor/MediaUpload.js index cebb547..76bf6f0 100644 --- a/public/assets/javascripts/ui/editor/MediaUpload.js +++ b/public/assets/javascripts/ui/editor/MediaUpload.js @@ -2,22 +2,94 @@ var MediaUpload = View.extend({ el: ".fileUpload", - action: "/api/media", + createAction: "/api/media/url", + uploadAction: "/api/media/upload", + + events: { + "keydown .url": "enterSubmit", + "change .file": "handleFileSelect", + }, initialize: function(opt){ this.parent = opt.parent + this.$url = this.$(".url") + this.$file = this.$(".file") + this.$upload = this.$(".upload-icon") }, show: function(){ this.$el.addClass("active") + this.$url.val("") }, hide: function(){ this.$el.removeClass("active") }, + + enterSubmit: function(e){ + if (e.keyCode == 13) { + e.preventDefault() + this.parse() + } + }, + + parse: function(){ + var url = this.$url.val() + this.$url.val("") + + Parser.parse(url, $.proxy(function(media){ + if (! media) { + alert("Not a valid image/video link") + return + } + + console.log(media) + + $.ajax({ + type: "post", + url: this.createAction, + data: rec, + success: $.proxy(this.add, this) + }) + }, this)) + }, + + handleFileSelect: function(e) { + e.stopPropagation(); + e.preventDefault(); - success: function(res){ - window.location.pathname = "/about/" + res.name + var files = e.dataTransfer ? e.dataTransfer.files : e.target.files; + + for (var i = 0, f; f = files[i]; i++) { + if ( ! f.type.match('image.*')) { + continue; + } + + this.$upload.addClass('uploading') + + var xhr = new XMLHttpRequest(), + fd = new FormData(); + + fd.append( 'file', f ); + + xhr.addEventListener("error", $.proxy(function(){ + console.log("error uploading file..") + this.$upload.removeClass('uploading') + }, this), false); + + xhr.onreadystatechange = $.proxy(function() { + if (xhr.readyState == 4 && xhr.status == 200) { + this.$upload.removeClass('uploading') + } + }, this) + + xhr.open("POST", '/api/media/upload', true); + xhr.send( fd ); + } }, + + add: function(media){ + } }) + diff --git a/public/assets/javascripts/ui/editor/MediaViewer.js b/public/assets/javascripts/ui/editor/MediaViewer.js index 8413e70..cd58231 100644 --- a/public/assets/javascripts/ui/editor/MediaViewer.js +++ b/public/assets/javascripts/ui/editor/MediaViewer.js @@ -15,13 +15,12 @@ var MediaViewer = ModalView.extend({ }, load: function(){ - $.get("/api/media/user", $.proxy(this.populate, this) + $.get("/api/media/user", $.proxy(this.populate, this)) }, populate: function(data){ data.forEach($.proxy(function(room){ var $span = $("<span>") - // $span.html(JSON.stringify(room)) $span.data("slug", room.slug) $span.css("background-image", "url(" + room.photo + ")") diff --git a/public/assets/javascripts/ui/lib/AlertModal.js b/public/assets/javascripts/ui/lib/AlertModal.js index 1aeb048..1b0f40f 100644 --- a/public/assets/javascripts/ui/lib/AlertModal.js +++ b/public/assets/javascripts/ui/lib/AlertModal.js @@ -23,4 +23,3 @@ var AlertModal = new( ModalFormView.extend({ } })) - diff --git a/public/assets/javascripts/ui/lib/Parser.js b/public/assets/javascripts/ui/lib/Parser.js new file mode 100644 index 0000000..545ed41 --- /dev/null +++ b/public/assets/javascripts/ui/lib/Parser.js @@ -0,0 +1,96 @@ +var Parser = { + integrations: [{ + type: 'image', + regex: /\.(jpeg|jpg|gif|png|svg)(\?.*)?$/i, + async: false, + fetch: function(url, done) { + done("", "") + }, + tag: function (media) { + return '<img src="' + media.url + '" onerror="imgError(this);">'; + } + }, { + type: 'youtube', + regex: /(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/ ]{11})/i, + async: false, + fetch: function(url, done) { + var id = (url.match(/v=([-_a-zA-Z0-9]{11})/i) || url.match(/youtu.be\/([-_a-zA-Z0-9]{11})/i) || url.match(/embed\/([-_a-zA-Z0-9]{11})/i))[1].split('&')[0]; + var thumb = "http://i.ytimg.com/vi/" + id + "/hqdefault.jpg" + done(id, thumb); + }, + tag: function (media) { + return '<img class="video" type="youtube" vid="'+media.token+'" src="'+media.thumbnail+'"><span class="playvid">▶</span>'; + } + }, { + type: 'vimeo', + regex: /vimeo.com\/\d+$/i, + async: true, + fetch: function(url, done) { + var id = url.match(/\d+$/i)[0]; + $.ajax({ + type: 'GET', + url: 'http://vimeo.com/api/v2/video/' + id + '.json', + success: function(result){ + if (result.length == 0) { return done(id, "") } + done(id, result[0].thumbnail_large) + } + }) + }, + tag: function (media) { + return '<img class="video" type="vimeo" vid="'+media.token+'" src="'+media.thumbnail+'"><span class="playvid">▶</span>'; + } + }, + /* + { + type: 'soundcloud', + regex: /soundcloud.com\/[-a-zA-Z0-9]+\/[-a-zA-Z0-9]+\/?$/i, + async: true, + fetch: function (url, done) { + $.ajax({ + type: 'GET', + url: 'http://api.soundcloud.com/resolve.json?url=' + + url + + '&client_id=' + + '0673fbe6fc794a7750f680747e863b10', + success: function(result) { + done(result.id, ""); + } + }); + }, + tag: function (media) { + return '<iframe width="400" height="166" scrolling="no" frameborder="no"' + + 'src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/' + media.token + + '&color=ff6600&auto_play=false&show_artwork=true"></iframe>' + } + }, { + type: 'link', + regex: /^http.+/i, + async: false, + fetch: function(url, done) { + done("", "") + }, + tag: function (media) { + return '<a href="' + media.url + '" target="_blank">' + media.url + '</a>' + } + } + */ + ], + + parse: function (url, cb) { + Parser.integrations.some(function(integration){ + if (integration.regex.test(url)) { + integration.fetch(url, function(token, thumbnail){ + cb({ + token: token, + thumbnail: thumbnail, + type: integration.type, + url: url, + }) + }) + return true + } + return false + }) + cb(null) + } +}
\ No newline at end of file diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index 18d0788..29eb3c8 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -828,9 +828,19 @@ h5{ transform:translateY(0%); } -.fileUpload .icon-ios7-upload-outline{ +.fileUpload .icon-ios7-upload-outline { font-size:40px; } +.fileUpload .upload-icon.uploading { +} +.fileUpload .upload-icon.uploading:before { + content: ' ' !important; + background-image: url("/assets/img/loader.gif"); + background-repeat: no-repeat; + width: 40px; + height: 40px; +} + .fileUpload input[type="text"]{ border: 1px solid #ccc; font-size: 15px; diff --git a/server/lib/api/media.js b/server/lib/api/media.js new file mode 100644 index 0000000..089e327 --- /dev/null +++ b/server/lib/api/media.js @@ -0,0 +1,46 @@ +/* jshint node: true */ + +var _ = require('lodash'), + crypto = require('crypto'), + util = require('../util'), + upload = require('../upload'), + config = require('../../../config.json'), + Media = require('../schemas/Media'); + +var media = { + user: function(req, res){ + Media.find({ user_id: req.user._id }, function(err, media){ + res.json(media || []) + }) + }, + + upload: function(req, res){ + var data = util.cleanQuery(req.body) + data.updated_at = new Date () + + if (req.files.avatar) { + upload.put("avatars", req.files.avatar, { + unacceptable: function(err){ + res.json({ error: { errors: { avatar: { message: "Problem saving avatar: " + err } } } }) + }, + success: function(url){ + data.photo = url + done() + } + }) + } + else { + done() + } + + function done () { + _.extend( req.user, data ) + req.user.save(function(err, msg) { + err ? res.json({ status: "FAIL", error: err }) + : res.json({ status: "OK", payload: req.user }) + }) + } + } +} + +module.exports = media diff --git a/server/lib/schemas/Media.js b/server/lib/schemas/Media.js new file mode 100644 index 0000000..a5d0c78 --- /dev/null +++ b/server/lib/schemas/Media.js @@ -0,0 +1,26 @@ +/* jshint node: true */ + +var mongoose = require('mongoose'), + _ = require('lodash'), + util = require('../util'); + +var MediaSchema = new mongoose.Schema({ + type: { + type: String, + required: true + }, + url: { + type: String, + required: true, + }, + thumbnail: { + type: String, + default: "" + }, + user_id: { type: mongoose.Schema.ObjectId, index: true }, + created_at: { type: Date }, + updated_at: { type: Date }, +}); + +module.exports = exports = mongoose.model('media', MediaSchema) +exports.schema = MediaSchema; diff --git a/views/controls/editor/media-drawer.ejs b/views/controls/editor/media-drawer.ejs index f5debec..4d8b596 100644 --- a/views/controls/editor/media-drawer.ejs +++ b/views/controls/editor/media-drawer.ejs @@ -1,11 +1,11 @@ <span class="fileUpload"> <form> - <span class="icon-ios7-upload-outline"></span><br> + <span class="icon-ios7-upload-outline upload-icon"></span><br> Upload File - <input type="file" name="pic" accept="image/*"> + <input type="file" accept="image/*" class="file"> </form> <small>~ or ~</small><br> - <input type="text" placeholder="Enter Vimeo or YouTube Link"></input> + <input type="text" placeholder="Enter Vimeo or YouTube Link" class="url"> </span> <div class="ants"> diff --git a/views/partials/scripts.ejs b/views/partials/scripts.ejs index a67b80c..981acef 100644 --- a/views/partials/scripts.ejs +++ b/views/partials/scripts.ejs @@ -50,6 +50,7 @@ <script type="text/javascript" src="/assets/javascripts/ui/lib/AlertModal.js"></script> <script type="text/javascript" src="/assets/javascripts/ui/lib/ConfirmModal.js"></script> <script type="text/javascript" src="/assets/javascripts/ui/lib/ErrorModal.js"></script> +<script type="text/javascript" src="/assets/javascripts/ui/lib/Parser.js"></script> <script type="text/javascript" src="/assets/javascripts/ui/site/SignInModal.js"></script> <script type="text/javascript" src="/assets/javascripts/ui/site/SignUpModal.js"></script> |
