/**
* @module Shared
*/
/**
* I am the ResourceManager.
*
* I contain the business logic for managing all Resources and rendering lists of them for display.
*
* I am closely connected with {{#crossLink "ViewResource"}}ViewResource{{/crossLink}}.
*
* @class ResourceManager
* @static
*/
FrameTrail.defineModule('ResourceManager', function(){
var maxUploadBytes,
tmpObj;
/**
* I tell the {{#crossLink "Database/loadResourceData:method"}}Database{{/crossLink}} to reload the index data.
* @method updateResourceDatabase
*/
function updateResourceDatabase() {
FrameTrail.module('Database').loadResourceData();
};
//Check for valid URL
$(document).on('paste blur input', '#resourceInputTabURL input', function(evt) {
checkResourceInput( this.value, $('#resourceNameInput')[0].value );
evt.stopPropagation();
});
//Check for Name Length
$(document).on('change paste keyup input', '#resourceNameInput', function(evt) {
if ( $(this).val().length > 2 ) {
$('#NewResourceConfirm').button('enable');
} else {
$('#NewResourceConfirm').button('disable');
}
evt.stopPropagation();
});
/**
* I open a jquery UI dialog, which allows the user to upload a new resource.
* When the onlyVideo parameter is set to true, I allow only uploads of videos (needed during creation of a new hypervideo)
*
* @method uploadResource
* @param {Function} successCallback
* @param {Boolean} onlyVideo
*
*/
function uploadResource(successCallback, onlyVideo) {
FrameTrail.module('UserManagement').ensureAuthenticated(function(){
$.ajax({
type: 'GET',
url: '../_server/ajaxServer.php',
data: {'a':'fileGetMaxUploadSize'},
success: function(response) {
maxUploadBytes = response.maxuploadbytes;
var projectID = FrameTrail.module('RouteNavigation').projectID,
uploadDialog = $('<div id="UploadDialog" title="Add New Resource">'
+ ' <form id="UploadForm" method="post">'
+ ' <div class="resourceInputTabContainer">'
+ ' <ul class="resourceInputTabList">'
+ ' <li data-type="url"><a href="#resourceInputTabURL">Paste URL</a></li>'
+ ' <li data-type="image"><a href="#resourceInputTabImage">Upload Image</a></li>'
+ ' <li data-type="video"><a href="#resourceInputTabVideo">Upload Video</a></li>'
+ ' <li data-type="map"><a href="#resourceInputTabMap">Add Map</a></li>'
+ ' </ul>'
+ ' <div id="resourceInputTabURL">'
+ ' <div id="resourceInputMessage" class="message active">Paste any URL (eg. http://example.com).<br>Some types will be detected automatically (ie. Image, Wikipedia, Youtube, Vimeo).</div>'
+ ' <input type="text" name="test" placeholder="URL" id="resourceInput">'
+ ' </div>'
+ ' <div id="resourceInputTabImage">'
+ ' <div class="message active">Add image file in the format <b>jpg, jpeg, gif, png</b>. Maximum File Size: <b>3 MB</b></div>'
+ ' <input type="file" name="image">'
+ ' </div>'
+ ' <div id="resourceInputTabVideo">'
+ ' <div id="videoInputMessage" class="message active">Add video files in the <u>two</u> formats <b>webm</b> & <b>mp4</b>. Maximum File Size: <b>'+ bytesToSize(maxUploadBytes) +'</b>.<br>For more info on video conversion see http://www.mirovideoconverter.com.</div>'
+ ' <input type="file" name="webm"> .webm<br>'
+ ' <input type="file" name="mp4"> .mp4'
+ ' </div>'
+ ' <div id="resourceInputTabMap">'
+ ' <div id="locationSearchWrapper">'
+ ' <input type="text" name="locationQ" id="locationQ" placeholder="Location Search">'
+ ' <span id="locationSearchCopyright">Data © OpenStreetMap contributors, ODbL 1.0.</span>'
+ ' <ul id="locationSearchSuggestions"></ul>'
+ ' </div>'
+ ' <input type="text" name="lat" placeholder="latitude">'
+ ' <input type="text" name="lon" placeholder="longitude">'
+ ' <input type="hidden" name="boundingBox[]" id="BB1">'
+ ' <input type="hidden" name="boundingBox[]" id="BB2">'
+ ' <input type="hidden" name="boundingBox[]" id="BB3">'
+ ' <input type="hidden" name="boundingBox[]" id="BB4">'
+ ' </div>'
+ ' </div>'
+ ' <div id="nameInputContainer">'
+ ' <div id="nameInputMessage">Name</div>'
+ ' <input type="text" name="name" placeholder="Enter a name for the new resource" id="resourceNameInput">'
+ ' <input type="hidden" name="a" value="fileUpload">'
+ ' <input type="hidden" name="projectID" value="'+ projectID +'">'
+ ' <input type="hidden" name="attributes" value="">'
+ ' <input type="hidden" name="type" value="url">'
+ ' </div>'
+ ' </form>'
+ ' <div class="progress">'
+ ' <div class="bar"></div >'
+ ' <div class="percent">0%</div >'
+ ' <div class="uploadStatus"></div>'
+ ' </div>'
+ '</div>'
+ '</div>');
uploadDialog.find('input[type="file"]').on('change', function() {
if (this.files[0].size > maxUploadBytes) {
uploadDialog.find('#NewResourceConfirm').prop('disabled', true);
$('#UploadDialog').append('<div class="message active error">File size is too big. Maximum size due to server settings: '+ bytesToSize(maxUploadBytes) +'. <br>Please ask your server administrator to allow a bigger upload size, post size, memory limit and longer execution time in the PHP settings.</div>');
} else {
uploadDialog.find('#NewResourceConfirm').prop('disabled', false);
uploadDialog.find('.message.error').remove();
}
});
uploadDialog.find('.resourceInputTabContainer').tabs({
activate: function(e,ui) {
uploadDialog.find('#nameInputContainer input[name="attributes"]').val('');
uploadDialog.find('#nameInputContainer input[name="type"]').val($(ui.newTab[0]).data('type'));
uploadDialog.find('.message.error').remove();
},
create: function(e,ui) {
if (onlyVideo) {
uploadDialog.find('.resourceInputTabContainer').tabs(
'option',
'active',
uploadDialog.find('#resourceInputTabVideo').index() - 1
);
uploadDialog.find('.resourceInputTabContainer').tabs('disable');
uploadDialog.find('.resourceInputTabContainer').tabs('enable', '#resourceInputTabVideo');
}
}
});
uploadDialog.find('#locationQ').keyup(function(e) {
$.getJSON('http://nominatim.openstreetmap.org/search?q='+ uploadDialog.find('#locationQ').val() + '&format=json')
.done(function(respText) {
uploadDialog.find('#locationSearchSuggestions').empty();
uploadDialog.find('#locationSearchSuggestions').show();
for (var location in respText) {
var suggestion = $('<li data-lon="'+ respText[location].lon +'" data-lat="'+ respText[location].lat +'" data-display-name="'+ respText[location].display_name +'" data-bb1="'+ respText[location].boundingbox[0] +'" data-bb2="'+ respText[location].boundingbox[1] +'" data-bb3="'+ respText[location].boundingbox[2] +'" data-bb4="'+ respText[location].boundingbox[3] +'">'+ respText[location].display_name +'</li>')
.click(function() {
uploadDialog.find('input[name="lon"]').val( $(this).attr('data-lon') );
uploadDialog.find('input[name="lat"]').val( $(this).attr('data-lat') );
uploadDialog.find('input#BB1').val( $(this).attr('data-bb1') );
uploadDialog.find('input#BB2').val( $(this).attr('data-bb2') );
uploadDialog.find('input#BB3').val( $(this).attr('data-bb3') );
uploadDialog.find('input#BB4').val( $(this).attr('data-bb4') );
uploadDialog.find('input[name="name"]').val( $(this).attr('data-display-name') );
uploadDialog.find('#locationSearchSuggestions').hide();
})
.appendTo( uploadDialog.find('#locationSearchSuggestions') );
}
//console.log(respText);
});
});
//Ajaxform
uploadDialog.find('#UploadForm').ajaxForm({
method: 'POST',
url: '../_server/ajaxServer.php',
beforeSerialize: function() {
uploadDialog.find('.message.error').remove();
var tmpType = uploadDialog.find('#nameInputContainer input[name="type"]').val();
if (tmpType == 'url') {
tmpObj = checkResourceInput( uploadDialog.find('#resourceInput').val(), uploadDialog.find('#resourceNameInput').val() );
uploadDialog.find('#nameInputContainer input[name="attributes"]').val(JSON.stringify(tmpObj));
tmpObj = [];
}
else if (tmpType == 'image') {
uploadDialog.find('#resourceInputTabVideo input').prop('disabled',true);
}
else if (tmpType == 'video') {
uploadDialog.find('#resourceInputTabImage input').prop('disabled',true);
}
var percentVal = '0%';
uploadDialog.find('.bar').width(percentVal);
uploadDialog.find('.percent').html(percentVal);
uploadDialog.find('.uploadStatus').html('Uploading Resource ...');
uploadDialog.find('.progress').show();
$('#NewResourceConfirm').prop('disabled', true);
},
beforeSend: function(xhr) {
var tmpType = uploadDialog.find('#nameInputContainer input[name="type"]').val();
// client side pre-validation to prevent upload of one file (server checks again)
if (tmpType == 'video') {
if( uploadDialog.find('[name="webm"]').val().length < 4 || uploadDialog.find('[name="mp4"]').val().length < 4) {
uploadDialog.find('.progress').hide();
uploadDialog.find('#NewResourceConfirm').prop('disabled', false);
$('#UploadDialog').append('<div class="message active error">Please choose <b>TWO</b> video files (first WEBM, second MP4)</div>');
xhr.abort();
}
}
},
data: tmpObj,
uploadProgress: function(event, position, total, percentComplete) {
var percentVal = percentComplete + '%';
uploadDialog.find('.bar').width(percentVal)
uploadDialog.find('.percent').html(percentVal);
},
success: function(respText) {
var percentVal = '100%';
uploadDialog.find('.bar').width(percentVal)
uploadDialog.find('.percent').html(percentVal);
switch (respText['code']) {
case 0:
// Upload Successful
if (respText['response']['resource']['type'] == 'video') {
uploadDialog.find('.uploadStatus').html('Generating Thumbnail ...');
var tmpVideo = $('<video id="tmpVideo" style="visibility: hidden; height: 300px; width: 400px; position: absolute;"></video>');
var tmpCanvas = $('<canvas id="tmpCanvas" width="400px" height="300px" style="visibility: hidden; position: absolute;"></canvas>');
$('body').append(tmpVideo);
$('body').append(tmpCanvas);
var video = document.getElementById('tmpVideo');
var canvas = document.getElementById('tmpCanvas');
if (video.canPlayType('video/webm')) {
video.src = FrameTrail.module('RouteNavigation').getResourceURL(respText['response']['resource']['src']);
} else if ((video.canPlayType('video/mp4') || (video.canPlayType('video/mpeg4')))) {
video.src = FrameTrail.module('RouteNavigation').getResourceURL(respText['response']['resource']['attributes']['alternateVideoFile']);
} else {
alert('Video Playback Error. Thumbnail could not be generated.');
}
video.addEventListener('loadeddata', function() {
// Go to middle & Play
video.currentTime = video.duration/2;
video.play();
});
video.addEventListener('playing', function() {
// Adapt and adjust Video & Canvas Dimensions
//video.width = canvas.width = video.offsetWidth;
//video.height = canvas.height = video.offsetHeight;
// Draw current Video-Frame on Canvas
canvas.getContext('2d').drawImage(video, 0, 0, 400, 300);
video.pause();
try {
canvas.toDataURL();
$.ajax({
url: '../_server/ajaxServer.php',
type: 'post',
data: {'a':'fileUploadThumb','projectID':projectID,'resourcesID':respText['response']['resId'],'type':respText['response']['resource']['type'],'thumb':canvas.toDataURL()},
/**
* Description
* @method success
* @return
*/
success: function() {
$(video).remove();
$(canvas).remove();
//addResource(respText["res"]);
FrameTrail.module('Database').loadResourceData(function() {
uploadDialog.dialog('close');
successCallback && successCallback.call();
});
}
});
} catch(error) {
$(image).remove();
$(canvas).remove();
FrameTrail.module('Database').loadResourceData(function() {
uploadDialog.dialog('close');
successCallback && successCallback.call();
});
}
});
} else if (respText['response']['resource']['type'] == 'image'
&& (/\.(jpg|jpeg|png)$/i.exec(respText['response']['resource']['src'])) ) {
uploadDialog.find('.uploadStatus').html('Generating Thumbnail ...');
var tmpImage = $('<img id="tmpImage" style="visibility: hidden; height: 250px; width:350px; position: absolute;"/>');
var tmpCanvas = $('<canvas id="tmpCanvas" width="350px" height="250px" style="visibility:hidden; position: absolute;"></canvas>');
$('body').append(tmpImage);
$('body').append(tmpCanvas);
var image = document.getElementById('tmpImage');
var canvas = document.getElementById('tmpCanvas');
image.src = FrameTrail.module('RouteNavigation').getResourceURL(respText['response']['resource']['src']);
image.addEventListener('load', function() {
// Adapt and adjust Image & Canvas Dimensions
//image.width = canvas.width = image.offsetWidth;
//image.height = canvas.height = image.offsetHeight;
// Draw current Image on Canvas
canvas.getContext('2d').drawImage(image, 0, 0, 350, 250);
try {
canvas.toDataURL();
$.ajax({
url: '../_server/ajaxServer.php',
type: 'post',
data: {'a':'fileUploadThumb','projectID':projectID,'resourcesID':respText['response']['resId'],'type':respText['response']['resource']['type'],'thumb':canvas.toDataURL()},
success: function() {
$(image).remove();
$(canvas).remove();
//addResource(respText["res"]);
FrameTrail.module('Database').loadResourceData(function() {
uploadDialog.dialog('close');
successCallback && successCallback.call();
});
}
});
} catch(error) {
$(image).remove();
$(canvas).remove();
FrameTrail.module('Database').loadResourceData(function() {
uploadDialog.dialog('close');
successCallback && successCallback.call();
});
}
});
} else {
//addResource(respText['response']);
FrameTrail.module('Database').loadResourceData(function() {
uploadDialog.dialog('close');
successCallback && successCallback.call();
});
}
break;
case 1:
uploadDialog.find('.progress').hide();
uploadDialog.find('#NewResourceConfirm').prop('disabled', false);
$('#UploadDialog').append('<div class="message active error">You are not logged in anymore.</div>');
break;
case 2:
uploadDialog.find('.progress').hide();
uploadDialog.find('#NewResourceConfirm').prop('disabled', false);
$('#UploadDialog').append('<div class="message active error">You are not activated.</div>');
break;
case 3:
uploadDialog.find('.progress').hide();
uploadDialog.find('#NewResourceConfirm').prop('disabled', false);
$('#UploadDialog').append('<div class="message active error">Could not find the projects resources folder.</div>');
break;
case 4:
uploadDialog.find('.progress').hide();
uploadDialog.find('#NewResourceConfirm').prop('disabled', false);
$('#UploadDialog').append('<div class="message active error">Please choose an image file</div>');
break;
case 5:
uploadDialog.find('.progress').hide();
uploadDialog.find('#NewResourceConfirm').prop('disabled', false);
$('#UploadDialog').append('<div class="message active error">Please choose <b>TWO</b> video files</div>');
break;
case 6:
uploadDialog.find('.progress').hide();
uploadDialog.find('#NewResourceConfirm').prop('disabled', false);
$('#UploadDialog').append('<div class="message active error">Please make sure you choose the right video format (.webm & .mp4)</div>');
break;
case 7:
uploadDialog.find('.progress').hide();
uploadDialog.find('#NewResourceConfirm').prop('disabled', false);
$('#UploadDialog').append('<div class="message active error">Type "map" was expected but $lat or $lon are empty</div>');
break;
case 8:
uploadDialog.find('.progress').hide();
uploadDialog.find('#NewResourceConfirm').prop('disabled', false);
$('#UploadDialog').append('<div class="message active error">Type or Name were empty. Did you add a Resource Name?</div>');
break;
case 9:
uploadDialog.find('.progress').hide();
uploadDialog.find('#NewResourceConfirm').prop('disabled', false);
$('#UploadDialog').append('<div class="message active error">Wrong Type</div>');
break;
case 10:
uploadDialog.find('.progress').hide();
uploadDialog.find('#NewResourceConfirm').prop('disabled', false);
$('#UploadDialog').append('<div class="message active error">File size is too big. Please ask the server administrator to allow a bigger upload size, post size and longer execution time.</div>');
break;
case 11:
uploadDialog.find('.progress').hide();
uploadDialog.find('#NewResourceConfirm').prop('disabled', false);
$('#UploadDialog').append('<div class="message active error">Empty field: URL. Please provide a valid url.</div>');
break;
case 20:
uploadDialog.find('.progress').hide();
uploadDialog.find('#NewResourceConfirm').prop('disabled', false);
$('#UploadDialog').append('<div class="message active error">You are not allowed to upload files.</div>');
break;
default:
uploadDialog.find('.progress').hide();
uploadDialog.find('#NewResourceConfirm').prop('disabled', false);
$('#UploadDialog').append('<div class="message active error">Something went wrong</div>');
break;
}
}
});
uploadDialog.dialog({
resizable: false,
width: 640,
height: 'auto',
modal: true,
close: function() {
$(this).dialog('close');
//$(this).find('#UploadForm').resetForm();
$(this).remove();
},
closeOnEscape: false,
buttons: [
{
id: 'NewResourceConfirm',
text: 'Add Resource',
click: function() {
//addResource( checkResourceInput( $('#resourceInput')[0].value, $('#resourceNameInput')[0].value ) );
$('#UploadForm').submit();
}
},
{
text: 'Cancel',
click: function() {
$(this).dialog('close');
}
}
],
open: function( event, ui ) {
$('#NewResourceConfirm').prop('disabled', true);
}
});
}
});
});
}
/**
* I calculate from the numeric bytesize a human readable string
* @method bytesToSize
* @param {Number} bytes
* @return String
*/
function bytesToSize(bytes) {
var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
if (bytes == 0) return '0 Byte';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i];
}
/**
* I perform some client-side validations on an URI input field
* @method checkResourceInput
* @param {String} uriValue
* @param {String} nameValue
* @return
*/
function checkResourceInput(uriValue, nameValue) {
if ( uriValue.length > 3 ) {
var newResource = null;
var checkers = [
function (src, name) {
// Wikipedia
var res = /wikipedia\.org\/wiki\//.exec(src);
if (res !== null) {
return createResource(src, "wikipedia", name);
}
return null;
},
function (src, name) {
// Youtube
// Check various patterns
var yt_list = [ /youtube\.com\/watch\?v=([^\&\?\/]+)/,
/youtube\.com\/embed\/([^\&\?\/]+)/,
/youtube\.com\/v\/([^\&\?\/]+)/,
/youtu\.be\/([^\&\?\/]+)/ ];
for (var i in yt_list) {
var res = yt_list[i].exec(src);
if (res !== null) {
return createResource("//www.youtube.com/embed/" + res[1],
"youtube", name, "http://img.youtube.com/vi/" + res[1] + "/2.jpg");
}
return null;
}
},
function (src, name) {
// Vimeo
var res = /^http:\/\/(www\.)?vimeo\.com\/(clip\:)?(\d+).*$/.exec(src);
if (res !== null) {
// Create the resource beforehand, so that we can update its thumb property asynchronously
var r = createResource("//player.vimeo.com/video/" + res[3], "vimeo", name);
$.ajax({
url: "http://vimeo.com/api/v2/video/" + res[3] + ".json",
async: false
}).success( function (data) {
r.thumb = data[0].thumbnail_large;
var vimeoID = data[0].id.toString();
if (!r.name || r.name == vimeoID) {
r.name = data[0].title;
}
});
return r;
} else {
return null;
}
},
function (src, name) {
// OpenStreeMap
var res = /www\.openstreetmap\.org.+#map=(\d+)\/([\d.]+)\/([\d.]+)/.exec(src);
if (res) {
var r = createResource("", "location", name);
r.attributes.lat = res[2];
r.attributes.lon = res[3];
return r;
}
res = /www\.openstreetmap\.org.+lat=([\d.]+).+lon=([\d.]+)/.exec(src);
if (res) {
var r = createResource("", "location", name);
r.attributes.lat = res[1];
r.attributes.lon = res[2];
return r;
}
return null;
},
function (src, name) {
// Image
if (/\.(gif|jpg|jpeg|png)$/i.exec(src)) {
return createResource(src, "image", name, src);
} else {
// We should do a HEAD request and check the
// content-type but it is not possible to do sync
// cross-domain requests, so we should return a
// Future value.
return null;
}
return null;
},
function (src, name) {
// Default fallback, will work for any URL
if (/(http|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])/.exec(src)) {
var r = createResource(src, "webpage", name);
//r.thumb = "http://immediatenet.com/t/l3?Size=1024x768&URL="+src;
return r;
}
return null;
}
];
for (var i in checkers) {
newResource = checkers[i](uriValue, nameValue);
if (newResource !== null) {
$('#resourceInputMessage').attr('class', 'message active success').text('Valid '+ newResource.type +' URL' );
return newResource;
break;
} else {
$('#resourceInputMessage').attr('class', 'message active error').text('Not a valid URL (try adding http://)');
}
}
} else {
// uri value length <= 3
}
}
/**
* PLEASE DOCUMENT THIS.
*
*
* @method createResource
* @param {} src
* @param {} type
* @param {} name
* @param {} thumb
* @return r
*/
function createResource(src, type, name, thumb) {
var r = {};
r.src = src;
r.type = type;
r.name = name;
if (! r.name) {
// Use the url basename.
r.name = src.substring(src.lastIndexOf('/') + 1).replace(/_/g, " ").replace(/-/g, " ");
}
r.thumb = thumb;
r.attributes = {};
return r;
}
/**
* I delete a resource from the server.
*
* @method deleteResource
* @param {String} projectID
* @param {String} resourceID
* @param {Function} successCallback
* @param {Function} cancelCallback
*/
function deleteResource(projectID, resourceID, successCallback, cancelCallback) {
$.ajax({
type: 'POST',
url: '../_server/ajaxServer.php',
cache: false,
data: {
a: 'fileDelete',
projectID: projectID,
resourcesID: resourceID
}
}).done(function(data) {
if (data.code === 0) {
successCallback();
} else {
cancelCallback(data);
}
});
};
/**
* I render a list of thumbnails for either all resource items of the project,
* or a narrowed down set of them.
*
* The targetElement should be a <div> or likewise, and will afterwards contain
* the elements which were rendered from e.g. {{#crossLink "ResourceImage/renderThumb:method"}}ResourceImage/renderThumb{{/crossLink}}
*
* If filter is true, then the method will ask the server only for a list of resources which meet the key-condition-value requirements (e.g. "type" "==" "video"). See also server docs!
*
* Note: projectID must be set!
*
* @method renderList
* @param {HTMLElement} targetElement
* @param {Boolean} filter
* @param {String} projectID
* @param {String} key
* @param {String} condition
* @param {String} value
*/
function renderList(targetElement, filter, projectID, key, condition, value) {
targetElement.empty();
targetElement.append('<div id="LoadingScreen"><div class="workingSpinner dark"></div></div>');
if (filter) {
getFilteredList(targetElement, projectID, key, condition, value)
} else {
getCompleteList(targetElement)
}
};
/**
* I call the .renderThumb method for all Resource data objects in the array
* (e.g. {{#crossLink "ResourceImage/renderThumb:method"}}ResourceImage/renderThumb{{/crossLink}})
* and append the returned element to targetElement.
*
* @method renderResult
* @param {HTMLElement} targetElement
* @param {Array} array
* @private
*/
function renderResult(targetElement, array) {
for (var id in array) {
var resourceThumb = FrameTrail.newObject(
( 'Resource'
+ array[id].type.charAt(0).toUpperCase()
+ array[id].type.slice(1)),
array[id]
).renderThumb(id);
//add thumb to target element
targetElement.append(resourceThumb);
}
};
/**
* I am the method choosen, when {{#crossLink "ResourceManager/renderList:method"}}ResourceManager/renderList{{/crossLink}} is called
* with filter set to false.
*
* I update the {{#crossLink "Database/resources:attribute"}}resource database{{/crossLink}} and the render the result into the targetElement
*
* @method getCompleteList
* @param {HTMLElement} targetElement
* @private
*/
function getCompleteList(targetElement) {
var database = FrameTrail.module('Database');
database.loadResourceData(
function(){
renderResult(targetElement, database.resources);
targetElement.find('#LoadingScreen').fadeOut(600, function() {
$(this).remove();
});
},
function(errorMessage){
targetElement.find('#LoadingScreen').remove();
targetElement.append('<div id="LoadingErrorMessage"><div class="message error active">' + errorMessage + '</div></div>');
}
);
}
/**
* I am the method choosen, when {{#crossLink "ResourceManager/renderList:method"}}ResourceManager/renderList{{/crossLink}} is called
* with filter set to true.
*
* The server will be asked to return a list of resources, which meet the requierements specified with key, considition, value
* (e.g. "type" "==" "video" ). See the server docs for more details!
*
* @method getFilteredList
* @param {HTMLElement} targetElement
* @param {String} projectID
* @param {String} key
* @param {String} condition
* @param {String} value
* @private
*/
function getFilteredList(targetElement, projectID, key, condition, value) {
$.ajax({
type: 'POST',
url: '../_server/ajaxServer.php',
cache: false,
data: {
a: 'fileGetByFilter',
projectID: projectID,
key: key,
condition: condition,
value: value
}
}).done(function(data){
if (data.code === 0) {
renderResult(targetElement, data.result)
}
targetElement.find('#LoadingScreen').fadeOut(600, function() {
$(this).remove();
});
}).fail(function(errorMessage){
targetElement.find('#LoadingScreen').remove();
targetElement.append('<div id="LoadingErrorMessage"><div class="message error active">' + errorMessage + '</div></div>');
});
}
/**
* I render into the targetElement, which should be a <div> or likewise, a set of thumbnails.
* These thumbnails are draggable in the <div id="MainContainer"> to allow drop actions into timelines or into the overlay container.
*
* @method renderResourcePicker
* @param {HTMLElement} targetElement
*/
function renderResourcePicker(targetElement) {
var resourceDatabase = FrameTrail.module('Database').resources,
container = $( '<div id="ResourcePicker">'
+ ' <div id="ResourcePickerControls">'
//+ ' <button id="ManageResourcesButton">Manage Resources</button>'
+ ' <button id="AddResourcesButton" class="addResourceIcon" data-tooltip-right="Add Resource"></button>'
+ ' </div>'
+ ' <div id="ResourcePickerList"></div>'
+ '</div>'),
resourceList = container.find('#ResourcePickerList'),
resourceThumb;
container.find('#AddResourcesButton').click(function() {
FrameTrail.module('ResourceManager').uploadResource(function(){
FrameTrail.module('Database').loadResourceData(function() {
targetElement.empty();
renderResourcePicker(targetElement);
});
});
});
for (var i in resourceDatabase) {
resourceThumb = FrameTrail.newObject(
( 'Resource'
+ resourceDatabase[i].type.charAt(0).toUpperCase()
+ resourceDatabase[i].type.slice(1)),
resourceDatabase[i]
).renderThumb();
resourceThumb.draggable({
containment: '#MainContainer',
helper: 'clone',
revert: 'invalid',
revertDuration: 100,
appendTo: 'body',
distance: 10,
zIndex: 1000,
start: function( event, ui ) {
ui.helper.css({
top: $(event.currentTarget).offset().top + "px",
left: $(event.currentTarget).offset().left + "px",
width: $(event.currentTarget).width() + "px",
height: $(event.currentTarget).height() + "px"
});
$(event.currentTarget).addClass('dragPlaceholder');
},
stop: function( event, ui ) {
$(event.target).removeClass('dragPlaceholder');
}
});
resourceList.append(resourceThumb);
}
targetElement.append(container);
}
return {
renderList: renderList,
renderResourcePicker: renderResourcePicker,
updateResourceDatabase: updateResourceDatabase,
uploadResource: uploadResource,
deleteResource: deleteResource
};
});