summaryrefslogtreecommitdiff
path: root/themes/okadmin/public/js
diff options
context:
space:
mode:
Diffstat (limited to 'themes/okadmin/public/js')
-rw-r--r--themes/okadmin/public/js/app.js346
-rw-r--r--themes/okadmin/public/js/parser.js49
-rw-r--r--themes/okadmin/public/js/upload.js225
3 files changed, 529 insertions, 91 deletions
diff --git a/themes/okadmin/public/js/app.js b/themes/okadmin/public/js/app.js
index 4b8d98f..9891298 100644
--- a/themes/okadmin/public/js/app.js
+++ b/themes/okadmin/public/js/app.js
@@ -1,61 +1,333 @@
var OKAdmin = function(){
-
- OKUpload.bind()
- OKUpload.add = function(data){
- var url = data[0].extra.Location
- add_image(url)
- }
- function add_image(url){
- var imageTemplate = $("#captioned-image-template").html()
- var $el = $(imageTemplate)
- $el.find(".uri").val(url)
- $el.find("img").attr("src", url)
- $(".captioned-image-list ol").append($el)
- }
- $(".captioned-image-list ol").sortable()
- $(".captioned-image-list ol").disableSelection()
-
- $("#add-image-url").keydown(pressEnter(function(e){
- var url = $(this).val()
- $(this).val("")
- add_image(url)
- })})
-
- $(document).on("click", ".remove-image", function(){
- if (confirm("Delete this image?")) {
+
+ // initialize our multi-image uploader with an element and a template
+ $(".group.image-list").each(function(){
+ var parent = this
+ var uploader = new OKUpload ()
+ uploader.bind( this )
+ uploader.add = function(media){
+ var url = media.url
+ var imageTemplate = $(".image-template", parent).html()
+ var $el = $(imageTemplate)
+ $el.find(".uri").val(media.url)
+ $el.find(".image-width").val(media.width)
+ $el.find(".image-height").val(media.height)
+ $el.find("img").attr("src", media.url)
+ $("ol", parent).prepend($el)
+ }
+ })
+ // delete image from gallery
+ $(document).on("mousedown", ".image-list .remove", function(){
+ if (confirm("Remove this image?")) {
$(this).parent().remove()
}
})
-
- $(".video .url").keydown(pressEnter(function(){
+
+ // Add default date
+ $('.date input').each(function(i, el){
+ var value = el.getAttribute('value')
+ if (!value) {
+ el.setAttribute('value', toDateInputValue(new Date))
+ }
+
+ function toDateInputValue (date) {
+ var local = new Date(date);
+ local.setMinutes(date.getMinutes() - date.getTimezoneOffset());
+ return local.toJSON().slice(0,10);
+ }
+ })
+
+ // initialize our multimedia uploader with an element and a template
+ $(".group.media-list").each(function(){
+ var parent = this
+ var uploader = new OKUpload ()
+ uploader.bind( this )
+ uploader.add = function(media){
+ var url = media.url
+ var imageTemplate = $(".image-template", parent).html()
+ var $el = $(imageTemplate)
+ $el.find(".uri").val(media.url)
+ $el.find(".image-width").val(media.width)
+ $el.find(".image-height").val(media.height)
+ $el.find("img").attr("src", media.url)
+ $("ol", parent).prepend($el)
+ }
+ uploader.addMedia = function(media){
+ switch (media.type) {
+ case 'youtube':
+ case 'vimeo':
+ case 'video':
+ var videoTemplate = $(".video-template", parent).html()
+ var $el = $(videoTemplate)
+ $el.addClass("loaded")
+ $el.find(".video-type").val( media.type )
+ $el.find(".video-token").val( media.token )
+ $el.find(".video-uri").val( media.uri )
+ $el.find(".video-title").val( media.title )
+ $el.find(".video-thumb").val( media.thumbnail )
+ $el.find(".video-width").val( media.width )
+ $el.find(".video-height").val( media.height )
+ $el.find("img").attr("src", media.thumbnail )
+ $("ol", parent).prepend($el)
+ break
+ case 'audio':
+ var audioTemplate = $(".audio-template", parent).html()
+ var $el = $(audioTemplate)
+ $el.addClass("loaded")
+ $el.find(".audio-type").val( media.type )
+ $el.find(".audio-token").val( media.token )
+ $el.find(".audio-uri").val( media.uri )
+ $el.find(".audio-title").val( media.title )
+ $el.find(".audio-thumb").val( media.thumbnail )
+ $el.find(".audio-duration").val( media.duration )
+ $el.find("img").attr("src", media.thumbnail )
+ $("ol", parent).prepend($el)
+ break
+ case 'link':
+ var linkTemplate = $(".link-template", parent).html()
+ var $el = $(linkTemplate)
+ $el.addClass("loaded")
+ $el.find(".uri").val( media.url )
+ $("ol", parent).prepend($el)
+ break
+ default:
+ alert("Unsupported link type!")
+ }
+ }
+ })
+ // delete image from gallery
+ $(document).on("mousedown", ".media-list .remove", function(){
+ if (confirm("Remove this media?")) {
+ $(this).parent().remove()
+ }
+ })
+
+ // initialize our single image uploader with existing DOM
+ $(".group.image").each(function(){
+ var $el = $(this)
+ var uploader = new OKUpload ()
+ uploader.bind( this )
+ uploader.add = function(media){
+ console.log(media)
+ $el.find(".uri").val(media.url)
+ $el.find(".caption").val("")
+ $el.find(".image-width").val(media.width)
+ $el.find(".image-height").val(media.height)
+ $el.find("img").attr("src", media.url).show()
+ $el.addClass("loaded")
+ }
+ })
+ // delete image from single image entry
+ $(document).on("mousedown", ".image .remove", function(){
+ if (confirm("Remove this image?")) {
+ var $el = $(this).closest(".image")
+ $el.removeClass('loaded')
+ $el.find(".uri").val("")
+ $el.find(".image-width").val("")
+ $el.find(".image-height").val("")
+ $el.find(".caption").val("")
+ $el.find("img").attr("src", "")
+ }
+ })
+
+ // make the region sortable with drag-and-drop
+ $(".media-list ol, .image-list ol, .link-list .links").sortable()
+ $(".media-list ol, .image-list ol").disableSelection()
+
+ // populate a video field with info from our url parser
+ var last_url
+ $(".video .url").on("focus", function(){
+ var $el = $(this)
+ last_url = $el.val()
+ })
+ $(".video .url").on("keydown blur", pressEnter(function(){
var $el = $(this)
var url = $el.val()
+ if (url == last_url) { return }
Parser.parse( url, function(media){
console.log(url,media)
$el.parent().addClass("loaded")
$el.parent().find(".video-type").val( media.type )
$el.parent().find(".video-token").val( media.token )
+ $el.parent().find(".video-uri").val( media.url )
$el.parent().find(".video-title").val( media.title )
$el.parent().find(".video-thumb").val( media.thumbnail )
+ $el.parent().find(".video-width").val( media.width )
+ $el.parent().find(".video-height").val( media.height )
})
- }}))
-
- $("form").submit(function(){
- $(".image-element").each(function(index){
- $(this).find("input,textarea").each(function(){
- var field = $(this).attr("name").replace(/\[\]/, "[" + index + "]")
- $(this).attr("name", field)
+ }))
+
+ // Add a new link to the list
+ $('.link-list').on('click', '.add-link-btn', function addNewLink (e) {
+ e.preventDefault && e.preventDefault()
+ e.stopPropagation && e.stopPropagation()
+ var $delegate = $(e.delegateTarget)
+ var $list = $delegate.find('.links')
+ var linkCount = $list.find("li").length
+
+ var $linkText = $delegate.find(".link-input-new.link-text")
+ var $linkURI = $delegate.find(".link-input-new.link-uri")
+
+ var template = $delegate.find(".link-template").html()
+ template = template.replace(/\[\]/g, "[" + linkCount + "]")
+ var $el = $(template)
+ $el.find(".link-text").val( $linkText.val() )
+ $el.find(".link-uri").val( $linkURI.val() )
+ $list.append($el)
+ $linkText.val("")
+ $linkURI.val("")
+ })
+
+ // Remove a link from the list
+ $('.link-list').on('click', '.remove-link-btn', function(e) {
+ e.preventDefault()
+ e.stopPropagation()
+ var $target = $(e.target)
+ $target.closest("li").remove()
+ })
+
+ // fix post indexing in list-driven inputs
+ $(".main.resource form").submit(function(e){
+ var $id = $("[name=id]"), $title = $("[name=title]"), $menu = $("[name=menu]"), $section = $(".resource.main")
+ var id = $section.data("id"), type = $section.data("type")
+
+ if ($title.length && ! $title.val()) {
+ $title.focus()
+ alert("Please enter a title")
+ e.preventDefault()
+ return
+ }
+
+ if ($menu.length && ! $menu.val()) {
+ $menu.val( $title.val() )
+ }
+
+ // TODO: pass through whether this page is static
+ if (type === "page" && (id == "contact" || id == "about")) {
+ ;
+ }
+ else {
+ var slug = slugify( $title.val() )
+ $id.val( slug )
+ }
+
+ // Parse date input
+ $('.property .date').each(function(i, el) {
+ var name = $(el).parent('.property').data('name')
+ var $input = $(el).find('input')
+ var date = new Date($input.val())
+ // Set to middle of day so it is the same date
+ // for all locales
+ date.setUTCHours(12)
+ var dateString = date.toUTCString()
+ var normalizedInput = document.createElement('input')
+ $(normalizedInput).attr({
+ name: name,
+ type: 'text',
+ value: dateString
+ })
+ $input.remove()
+ $(el).append(normalizedInput)
+ })
+
+ // Modify flags checkboxes such that unchecked ones return "false"
+ // instead of nothing
+ $('.property input[type=checkbox]').each(function(i, el) {
+ var checked = !!el.checked
+ if (!checked) {
+ el.value = 'false'
+ el.setAttribute('checked', true)
+ }
+ })
+
+ $(".link-list").each(function(){
+ var $inputs = $(this).find(".link-input-new")
+ if ($inputs.eq(0).val() && $inputs.eq(1).val()) {
+ $(this).find(".add-link-btn").trigger("click")
+ }
+ })
+
+ $("ol").each(function(){
+ $("li", this).each(function(index){
+ $(this).find("input,textarea").each(function(){
+ var field = $(this).attr("name").replace(/\[[0-9]*\]/, "[" + index + "]")
+ $(this).attr("name", field)
+ })
})
})
})
+
+ // delete individual records
+ $("#delete_form").submit(function(e){
+ if (confirm("Are you sure you want to delete this record?")) {
+ return
+ }
+ else {
+ e.preventDefault()
+ }
+ })
+
+ // reorder items in categories
+ $(".resource-category:not(.grouped)").on("click", ".edit-btn", function(e) {
+ e.preventDefault();
+ var $parent = $(e.delegateTarget)
+ var $editBtn = $parent.find(".edit-btn");
+ var $cancelBtn = $parent.find(".cancel-btn");
+ var $saveBtn = $parent.find(".save-btn");
+ var $ol = $parent.find("ol");
+ var toggles = [$parent, $cancelBtn, $saveBtn, $editBtn];
+
+ $ol.sortable();
+ $ol.disableSelection();
+ toggle();
+
+ $cancelBtn.one("click", function(e) {
+ $ol.sortable("cancel");
+ $ol.enableSelection();
+ toggle();
+ });
+
+ $saveBtn.one("click", function(e) {
+ $ol.sortable();
+ toggle();
+ });
+
+ function toggle() {
+ toggles.forEach(function($el) {
+ $el.toggleClass('active');
+ })
+ }
+ });
+
+ // save new category order
+ $(".resource-category.root").on("submit", "form", function(e) {
+ var $parent = $(e.delegateTarget);
+ var $resources = $parent.find(".resource-input")
+ var isDescending = $parent.hasClass("descending")
+ $resources.each(function(index) {
+ var $input = $(this);
+ var parsed = JSON.parse($input.val());
+ if (isDescending) {
+ parsed.__index = $resources.length - index;
+ }
+ else {
+ parsed.__index = index;
+ }
+ $input.val(JSON.stringify(parsed));
+ })
+ });
- function pressEnter(fn){
- return function(e){
- if (e.keyCode !== 13) return
+ $(window).on('keydown', function(e){
+ if ( (e.ctrlKey || e.altKey || e.metaKey) && e.keyCode == 83 ) {
e.preventDefault()
+ $("#resource_form").submit()
}
- }
+ })
+}
$(function(){
window.app = new OKAdmin ()
})
+
+
+function slugify (s){ return (s || "").toLowerCase().replace(/\s/g,"-").replace(/[^-_a-zA-Z0-9]/g, '-').replace(/-+/g, "-") }
diff --git a/themes/okadmin/public/js/parser.js b/themes/okadmin/public/js/parser.js
index 411f425..81bba2d 100644
--- a/themes/okadmin/public/js/parser.js
+++ b/themes/okadmin/public/js/parser.js
@@ -31,15 +31,17 @@ var Parser = {
regex: /\.(mp4|webm)(\?.*)?$/i,
fetch: function(url, done) {
var video = document.createElement("video")
+ var url_parts = url.replace(/\?.*$/, "").split("/")
+ var filename = url_parts[ url_parts.length-1 ]
video.addEventListener("loadedmetadata", function(){
var width = video.videoWidth, height = video.videoHeight
video = null
done({
url: url,
type: "video",
- token: "",
- thumbnail: "",
- title: "",
+ token: url,
+ thumbnail: "http://okfocus.s3.amazonaws.com/misc/okcms/video.png",
+ title: filename,
width: width,
height: height,
})
@@ -51,6 +53,31 @@ var Parser = {
return '<video src="' + media.url + '">';
}
}, {
+ type: 'audio',
+ regex: /\.(wav|mp3)(\?.*)?$/i,
+ fetch: function(url, done) {
+ var audio = document.createElement("audio")
+ var url_parts = url.replace(/\?.*$/, "").split("/")
+ var filename = url_parts[ url_parts.length-1 ]
+ audio.addEventListener("loadedmetadata", function(){
+ var duration = audio.duration
+ audio = null
+ done({
+ url: url,
+ type: "audio",
+ token: url,
+ thumbnail: "http://okfocus.s3.amazonaws.com/misc/okcms/audio.png",
+ title: filename,
+ duration: duration,
+ })
+ })
+ audio.src = url
+ audio.load()
+ },
+ tag: function (media) {
+ return '<audio src="' + media.url + '">';
+ }
+ }, {
type: 'youtube',
regex: /(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/ ]{11})/i,
fetch: function(url, done) {
@@ -73,6 +100,8 @@ var Parser = {
token: id,
thumbnail: thumb,
title: res.snippet.title,
+ autoplay: false,
+ loop: false,
width: 640,
height: 360,
})
@@ -106,6 +135,8 @@ var Parser = {
title: res.title,
width: res.width,
height: res.height,
+ autoplay: false,
+ loop: false,
})
}
})
@@ -114,8 +145,7 @@ var Parser = {
// 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) {
@@ -126,13 +156,14 @@ var Parser = {
+ '&client_id='
+ '0673fbe6fc794a7750f680747e863b10',
success: function(result) {
- // console.log(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,
+ duration: result.duration,
width: 166,
height: 166,
})
@@ -145,7 +176,6 @@ var Parser = {
'&amp;color=ff6600&amp;auto_play=false&amp;show_artwork=true"></iframe>'
}
},
- /*
{
type: 'link',
regex: /^http.+/i,
@@ -163,8 +193,7 @@ var Parser = {
tag: function (media) {
return '<a href="' + media.url + '" target="_blank">' + media.url + '</a>'
}
- }
- */
+ },
],
tumblr: function(url, cb){
@@ -232,6 +261,8 @@ var Parser = {
title: stripHTML(post['video-caption']),
width: 640,
height: 360,
+ autoplay: false,
+ loop: false,
}
media_list.push(media)
}
diff --git a/themes/okadmin/public/js/upload.js b/themes/okadmin/public/js/upload.js
index d9fd5ed..6ff7ac9 100644
--- a/themes/okadmin/public/js/upload.js
+++ b/themes/okadmin/public/js/upload.js
@@ -1,56 +1,191 @@
-var OKUpload = {
- action: "/_services/image",
-
- bind: function(){
- var el = document.getElementById("file")
- if (! el) return
- el.addEventListener("change", OKUpload.handleFileSelect)
- },
+var OKUpload = function(){
+ this.config = $("#uploadConfig").data()
+ this.imageAction = "/_services/s3/image"
+ this.videoAction = "/_services/s3/video"
+ this.audioAction = "/_services/s3/audio"
+}
+OKUpload.prototype.bind = function(rapper){
+ var uploader = this
+ this.rapper = rapper
+ this.$progress = $("<div class='progress'>")
+ this.xhrCount = 0
+ this.loadCount = 0
+
+ $(this.rapper).append(this.$progress)
+ $(".add-image-button input", rapper).change( uploader.handleFileSelect.bind(uploader) )
+ $(".add-url", rapper).on("keydown blur", pressEnter( function(e){
+ var url = $(this).val()
+ $(this).val("")
+ uploader.parse(url)
+ }))
+}
+OKUpload.prototype.parse = function(url){
+ if (! url) return
+ var uploader = this
+ Parser.parse( url, function(media){
+ console.log(url, media)
+ if (! media) {
+ alert("Not a valid link")
+ }
+ else if (media.type == "image") {
+ uploader.add(media)
+ }
+ else {
+ uploader.addMedia(media)
+ }
+ })
+}
+OKUpload.prototype.handleFileSelect = function(e) {
+ e.stopPropagation();
+ e.preventDefault();
- handleFileSelect: function(e) {
- e.stopPropagation();
- e.preventDefault();
+ var files = e.dataTransfer ? e.dataTransfer.files : e.target.files;
- var files = e.dataTransfer ? e.dataTransfer.files : e.target.files;
+ for (var i = 0, f; f = files[i]; i++) {
+ this.upload(f)
+ }
+}
+OKUpload.prototype.largeFileError = function(file, maxSize) {
+ var your_bytes = bytesToString(file.size)
+ var max_bytes = bytesToString(maxSize)
+ alert("Sorry, your file is too big.\n\n" + file.name + "\n\nYour file: " + your_bytes + "\nMax size: " + max_bytes)
+ function bytesToString (n) {
+ if (n < 1024) return n + " bytes"
+ n /= 1024
+ if (n < 1024) return n.toFixed(1) + " kb"
+ n /= 1024
+ if (n < 1024) return n.toFixed(1) + " mb"
+ }
+}
+OKUpload.prototype.upload = function(f){
- for (var i = 0, f; f = files[i]; i++) {
- if ( ! f.type.match('image.*')) {
- continue;
- }
- OKUpload.upload(f)
+ var field, action
+
+ if ( f.type.match('video.*') ) {
+ if (this.config.videoMaxbytes && f.size > this.config.videoMaxbytes) {
+ return this.largeFileError(f, this.config.videoMaxbytes)
+ }
+ field = 'video'
+ action = this.videoAction
+ }
+ else if ( f.type.match('audio.*') ) {
+ if (this.config.audioMaxbytes && f.size > this.config.audioMaxbytes) {
+ return this.largeFileError(f, this.config.audioMaxbytes)
}
- },
+ field = 'audio'
+ action = this.audioAction
+ }
+ else {
+ if (this.config.imageMaxbytes && f.size > this.config.imageMaxbytes) {
+ return this.largeFileError(f, this.config.imageMaxbytes)
+ }
+ field = 'image'
+ action = this.imageAction || this.action
+ }
+
+ this.xhrCount += 1
- upload: function(f){
- var fd = new FormData()
- fd.append('image', f)
+ this.$progress.addClass("loading")
- var request = $.ajax({
- url: OKUpload.action,
- type: "post",
- data: fd,
- dataType: "json",
- processData: false,
- contentType: false,
- })
- request.done(OKUpload.success)
- },
+ var $loader = $("<div class='xhr'>")
+ var $loading_bar = $("<div>")
+ $loading_bar.css("width", "0%")
+ $loader.append( $loading_bar )
+ this.$progress.append($loader)
- success: function(media){
- if (media.error) {
- console.log(media.error)
- return
+ var fd = new FormData()
+ fd.append(field, f)
+
+ var request = new XMLHttpRequest()
+ request.open("POST", action, true)
+
+ request.addEventListener("progress", updateProgress.bind(this));
+ request.addEventListener("load", transferComplete.bind(this));
+ request.addEventListener("error", transferError.bind(this));
+ request.addEventListener("abort", transferAbort.bind(this));
+
+ function updateProgress (e) {
+ if (e.lengthComputable) {
+ var percentComplete = Math.round( 100 * e.loaded / e.total )
+ $loading_bar.css("width", percentComplete + "%")
}
- OKUpload.add(media)
- },
-
- add: function(media){
- console.log(media)
- },
-
- error: function(error){
- throw error
- },
+ }
+ function transferComplete (data) {
+ this.loadCount += 1
+ this.hideUploadBars()
+ if (request.readyState == 4 && request.status == 200) {
+ var responseData
+ try {
+ responseData = JSON.parse( request.responseText )
+ this.success( responseData )
+ }
+ catch (e) {
+ console.log(request.responseText)
+ console.log("ERROR PARSING JSON")
+ }
+ }
+ console.log(arguments, request)
+ }
+ function transferError (data) {
+ console.log("Transfer error")
+ this.loadCount += 1
+ this.hideUploadBars()
+ console.log(arguments)
+ }
+ function transferAbort (data) {
+ console.log("Transfer aborted")
+ this.loadCount += 1
+ this.hideUploadBars()
+ console.log(arguments)
+ }
+ request.send(fd)
+
+/*
+ var request = $.ajax({
+ url: this.action,
+ type: "post",
+ data: fd,
+ dataType: "json",
+ processData: false,
+ contentType: false,
+ })
+ request.done(this.success.bind(this))
+*/
}
+OKUpload.prototype.hideUploadBars = function () {
+ if (this.xhrCount == this.loadCount) {
+ this.$progress.removeClass("loading")
+ setTimeout(function(){
+ this.$progress.empty()
+ }.bind(this), 300)
+ }
+}
+OKUpload.prototype.success = function(data){
+ if (data.error) {
+ console.log(data.error)
+ return
+ }
+ var url = data.url
+ console.log(url)
+ this.parse(url)
+}
+OKUpload.prototype.add = function(media){
+ console.log(media)
+}
+OKUpload.prototype.addMedia = function(media){
+ console.log(media)
+}
+OKUpload.prototype.error = function(error){
+ throw error
+}
+
+
+function pressEnter(fn){
+ return function(e){
+ if (e.keyCode && e.keyCode !== 13) return
+ e.preventDefault()
+ fn.apply(this)
+ }
+} \ No newline at end of file