diff options
| -rw-r--r-- | app/node_modules/okschema/index.js | 5 | ||||
| -rw-r--r-- | examples/db.json | 4 | ||||
| -rw-r--r-- | themes/okadmin/public/css/main.css | 4 | ||||
| -rw-r--r-- | themes/okadmin/public/js/app.js | 16 | ||||
| -rw-r--r-- | themes/okadmin/public/js/parser.js | 282 | ||||
| -rw-r--r-- | themes/okadmin/templates/partials/inputs.liquid | 14 | ||||
| -rw-r--r-- | themes/okadmin/templates/partials/tail.liquid | 1 |
7 files changed, 321 insertions, 5 deletions
diff --git a/app/node_modules/okschema/index.js b/app/node_modules/okschema/index.js index 4e8ea73..6c7cf96 100644 --- a/app/node_modules/okschema/index.js +++ b/app/node_modules/okschema/index.js @@ -21,6 +21,11 @@ var types = { // Let parent handle validation assertValid: function(spec, value) {} }, + 'video': { + parent: {type: 'string'}, + // Let parent handle validation + assertValid: function(spec, value) {} + }, 'enum': { parent: {type: 'string'}, assertValid: function(spec, value) { diff --git a/examples/db.json b/examples/db.json index b2cdf4a..f7936d5 100644 --- a/examples/db.json +++ b/examples/db.json @@ -4,9 +4,9 @@ { "type": "pretzel", "description": "really a very tasty bread! yup yes", - "color": "blue", + "color": "green", "id": "pretzel", - "title": "" + "title": "Pretzel Chips" }, { "type": "bagel", diff --git a/themes/okadmin/public/css/main.css b/themes/okadmin/public/css/main.css index c5694eb..aff28fd 100644 --- a/themes/okadmin/public/css/main.css +++ b/themes/okadmin/public/css/main.css @@ -160,6 +160,10 @@ label { font-size: 1.0em; } +.disabled { + display: none; +} + .clear { clear: both; } diff --git a/themes/okadmin/public/js/app.js b/themes/okadmin/public/js/app.js index b850466..3abc347 100644 --- a/themes/okadmin/public/js/app.js +++ b/themes/okadmin/public/js/app.js @@ -1,11 +1,23 @@ var OKAdmin = function(){ - OKUpload.bind() OKUpload.add = function(data){ console.log(data) } + $(".video .url").change(function(){ + var $el = $(this) + var url = $el.val() + Parser.parse( url, function(media){ + $el.next(".video-type").val( media.type ) + $el.next(".video-token").val( media.token ) + $el.next(".video-title").val( media.title ) + $el.next(".video-thumb").val( media.thumbnail ) + }) + }) + } -window.app = new OKAdmin () +$(function(){ + window.app = new OKAdmin () +}) diff --git a/themes/okadmin/public/js/parser.js b/themes/okadmin/public/js/parser.js new file mode 100644 index 0000000..411f425 --- /dev/null +++ b/themes/okadmin/public/js/parser.js @@ -0,0 +1,282 @@ +var Parser = { + integrations: [{ + type: 'image', + regex: /\.(jpeg|jpg|gif|png|svg)(\?.*)?$/i, + fetch: function(url, done) { + var img = new Image () + img.onload = function(){ + if (!img) return + var width = img.naturalWidth, height = img.naturalHeight + img = null + done({ + url: url, + type: "image", + token: "", + thumbnail: "", + title: "", + width: width, + height: height, + }) + } + img.src = url + if (img.complete) { + img.onload() + } + }, + tag: function (media) { + return '<img src="' + media.url + '">'; + } + }, { + type: 'video', + regex: /\.(mp4|webm)(\?.*)?$/i, + fetch: function(url, done) { + var video = document.createElement("video") + video.addEventListener("loadedmetadata", function(){ + var width = video.videoWidth, height = video.videoHeight + video = null + done({ + url: url, + type: "video", + token: "", + thumbnail: "", + title: "", + width: width, + height: height, + }) + }) + video.src = url + video.load() + }, + tag: function (media) { + return '<video src="' + media.url + '">'; + } + }, { + type: 'youtube', + regex: /(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/ ]{11})/i, + 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" + $.ajax({ + type: 'GET', + url: 'https://www.googleapis.com/youtube/v3/videos', + dataType: "jsonp", + data: { + id: id, + key: "AIzaSyDYPKGD0-_VRBWpUYRmX8Qg6BtWmcPU_cM", + part: "id,contentDetails,snippet,status", + }, + success: function(result){ + var res = result.items[0] + done({ + url: url, + type: "youtube", + token: id, + thumbnail: thumb, + title: res.snippet.title, + width: 640, + height: 360, + }) + } + }) + }, + tag: function (media) { + // return '<img class="video" type="youtube" vid="'+media.token+'" src="'+media.thumbnail+'"><span class="playvid">▶</span>'; + return '<div class="video" style="width: ' + media.width + 'px; height: ' + media.height + 'px; overflow: hidden; position: relative;"><iframe frameborder="0" scrolling="no" seamless="seamless" webkitallowfullscreen="webkitAllowFullScreen" mozallowfullscreen="mozallowfullscreen" allowfullscreen="allowfullscreen" id="okplayer" width="' + media.width + '" height="' + media.height + '" src="http://youtube.com/embed/' + media.token + '?showinfo=0" style="position: absolute; top: 0px; left: 0px; width: ' + media.width + 'px; height: ' + media.height + 'px;"></iframe></div>' + } + }, { + type: 'vimeo', + regex: /vimeo.com\/\d+$/i, + 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, "", 640, 360) } + var res = result[0] + if (res.embed_privacy != "anywhere") { + AlertModal.alert("Sorry, the author of this video has marked it private, preventing it from being embedded.", function(){}) + return + } + done({ + url: url, + type: "vimeo", + token: id, + thumbnail: res.thumbnail_large, + title: res.title, + width: res.width, + height: res.height, + }) + } + }) + }, + tag: function (media) { + // return '<img class="video" type="vimeo" vid="'+media.token+'" src="'+media.thumbnail+'"><span class="playvid">▶</span>'; + return '<div class="video" style="width: ' + media.width + 'px; height: ' + media.height + 'px; overflow: hidden; position: relative;"><iframe frameborder="0" scrolling="no" seamless="seamless" webkitallowfullscreen="webkitAllowFullScreen" mozallowfullscreen="mozallowfullscreen" allowfullscreen="allowfullscreen" id="okplayer" src="http://player.vimeo.com/video/' + media.token + '?api=1&title=0&byline=0&portrait=0&playbar=0&player_id=okplayer&loop=0&autoplay=0" width="' + media.width + '" height="' + media.height + '" style="position: absolute; top: 0px; left: 0px; width: ' + media.width + 'px; height: ' + media.height + 'px;"></iframe></div>' + } + }, + { + type: 'soundcloud', + regex: /soundcloud.com\/[-a-zA-Z0-9]+\/[-a-zA-Z0-9]+\/?$/i, + fetch: function (url, done) { + $.ajax({ + type: 'GET', + url: 'http://api.soundcloud.com/resolve.json?url=' + + url + + '&client_id=' + + '0673fbe6fc794a7750f680747e863b10', + success: function(result) { + // console.log(result) + done({ + url: url, + type: "soundcloud", + token: result.id, + thumbnail: result.artwork_url || result.user.avatar_url, + title: result.user.username + " - " + result.title, + width: 166, + height: 166, + }) + } + }); + }, + tag: function (media) { + return '<iframe width="166" 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, + fetch: function(url, done) { + done({ + url: url, + type: "link", + token: "", + thumbnail: "", + title: "", + width: 100, + height: 100, + }) + }, + tag: function (media) { + return '<a href="' + media.url + '" target="_blank">' + media.url + '</a>' + } + } + */ + ], + + tumblr: function(url, cb){ + var domain = url.replace(/^https?:\/\//,"").split("/")[0] + if (domain.indexOf(".") == -1) { + domain += ".tumblr.com" + } + $.ajax({ + type: 'GET', + url: "http://" + domain + "/api/read", + dataType: "jsonp", + data: { + format: "json", + }, + success: function(data){ + var media_list = [] + var blog = data.tumblelog + + data.posts.forEach(parse) + cb(media_list) + + function parse(post){ + var media, caption, url + switch (post.type) { + case 'photo': + caption = stripHTML(post['photo-caption']) + if (post.photos.length) { + post.photos.forEach(function(photo){ + var media = { + url: photo['photo-url-1280'], + type: "image", + token: "", + thumbnail: photo['photo-url-500'], + description: caption, + width: parseInt(photo.width), + height: parseInt(photo.height), + } + media_list.push(media) + }) + } + else { + media = { + url: post['photo-url-1280'], + type: "image", + token: "", + thumbnail: post['photo-url-500'], + description: caption, + width: parseInt(post.width), + height: parseInt(post.height), + } + media_list.push(media) + } + break + case 'video': + url = post['video-source'] + if (url.indexOf("http") !== 0) { break } + if (Parser.lookup.youtube.regex.test(url)) { + 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" + media = { + url: post['video-source'], + type: "youtube", + token: id, + thumbnail: thumb, + title: stripHTML(post['video-caption']), + width: 640, + height: 360, + } + media_list.push(media) + } + break + } + } +// console.log(post) + } + }) + }, + + parse: function (url, cb) { + var matched = Parser.integrations.some(function(integration){ + if (integration.regex.test(url)) { + integration.fetch(url, function(res){ + cb(res) + }) + return true + } + return false + }) + if (! matched) { + cb(null) + } + }, + + tag: function (media){ + if (media.type in Parser.lookup) { + return Parser.lookup[media.type].tag(media) + } + return "" + }, + + loadImage: function(url, cb, error){ + if (Parser.lookup.image.regex.test(url)) { + Parser.lookup.image.fetch(url, function(media){ + cb(media) + }) + } + else error && error() + }, + + thumbnail: function (media) { + return '<img src="' + (media.thumbnail || media.url) + '" class="thumb">'; + }, + +}; +Parser.lookup = _.indexBy(Parser.integrations, 'type'); diff --git a/themes/okadmin/templates/partials/inputs.liquid b/themes/okadmin/templates/partials/inputs.liquid index 551a66c..42e459f 100644 --- a/themes/okadmin/templates/partials/inputs.liquid +++ b/themes/okadmin/templates/partials/inputs.liquid @@ -3,7 +3,7 @@ {% assign spec = pair[1] %} {% assign type = spec.type %} - <div class="property"> + <div class="property {% if spec.disabled %}hidden{% endif %}"> <label for="{{name}}">{{name | capitalize}}</label> {% if type == 'string' %} @@ -18,6 +18,14 @@ disabled="true" {% endif %} name="{{name}}">{{spec.value}}</textarea> + {% elsif type == 'video' %} + <div class="video group"> + <input name="{{name}}[url]" type="text" value="{{spec.value.url}}" class="url" placeholder="Enter a video URL"> + <input name="{{name}}[type]" type="text" value="{{spec.value.title}}" class="video-type" hidden> + <input name="{{name}}[token]" type="text" value="{{spec.value.title}}" class="video-token" hidden> + <input name="{{name}}[title]" type="text" value="{{spec.value.title}}" class="video-title" placeholder="Title"> + <input name="{{name}}[thumb]" type="text" value="{{spec.value.thumb}}" class="video-thumb" placeholder="Thumbnail"> + </div> {% elsif type == 'enum' %} <select {% if spec.disabled %} @@ -28,6 +36,10 @@ <option value="{{option}}" {% if option == spec.value %}selected{% endif %}>{{option}}</option> {% endfor %} </select> + {% elsif type == 'uri' %} + <div> + <input type="file" id="file"> + </div> {% else %} <p><pre style="color: red">Admin template doesn't support '{{type}}' properties!</pre></p> {% endif %} diff --git a/themes/okadmin/templates/partials/tail.liquid b/themes/okadmin/templates/partials/tail.liquid index 76d31b0..31da4ed 100644 --- a/themes/okadmin/templates/partials/tail.liquid +++ b/themes/okadmin/templates/partials/tail.liquid @@ -1,6 +1,7 @@ </div> {% comment %} closes container tag {% endcomment %} </body> <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> + <script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.6.0/lodash.min.js"></script> <script src="/_admin/js/upload.js"></script> <script src="/_admin/js/app.js"></script> </html> |
