summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/node_modules/okschema/index.js5
-rw-r--r--examples/db.json4
-rw-r--r--themes/okadmin/public/css/main.css4
-rw-r--r--themes/okadmin/public/js/app.js16
-rw-r--r--themes/okadmin/public/js/parser.js282
-rw-r--r--themes/okadmin/templates/partials/inputs.liquid14
-rw-r--r--themes/okadmin/templates/partials/tail.liquid1
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">&#9654;</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">&#9654;</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 +
+ '&amp;color=ff6600&amp;auto_play=false&amp;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>