first version of new upload interface
This commit is contained in:
parent
8feed54bf9
commit
6c013ebc92
20 changed files with 966 additions and 102 deletions
|
@ -852,6 +852,7 @@
|
|||
The plug-in architecture is not yet finalized, documentation forthcoming.
|
||||
*/
|
||||
"menuExtras": [
|
||||
"upload",
|
||||
"user",
|
||||
//"locale",
|
||||
"reload"
|
||||
|
|
|
@ -738,6 +738,7 @@
|
|||
The plug-in architecture is not yet finalized, documentation forthcoming.
|
||||
*/
|
||||
"menuExtras": [
|
||||
"upload",
|
||||
"user",
|
||||
//"locale",
|
||||
"reload"
|
||||
|
|
|
@ -672,6 +672,7 @@ examples (config.SITENAME.jsonc) that are part of this pan.do/ra distribution.
|
|||
The plug-in architecture is not yet finalized, documentation forthcoming.
|
||||
*/
|
||||
"menuExtras": [
|
||||
"upload",
|
||||
"user",
|
||||
// "locale",
|
||||
"reload"
|
||||
|
|
177
static/js/addFilesDialog.js
Normal file
177
static/js/addFilesDialog.js
Normal file
|
@ -0,0 +1,177 @@
|
|||
'use strict';
|
||||
|
||||
pandora.ui.addFilesDialog = function(options) {
|
||||
|
||||
var $button = Ox.Button({
|
||||
id: 'add',
|
||||
title: Ox._(Ox.toTitleCase(options.action))
|
||||
}).bindEvent({
|
||||
click: function() {
|
||||
$button.options({disabled: true});
|
||||
(options.action == 'upload' ? uploadVideos : importVideos)(function() {
|
||||
that.close();
|
||||
pandora.ui.tasksDialog({
|
||||
tasks: options.action == 'import' ? 'all' : 'uploads'
|
||||
}).open();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var $list = Ox.TableList({
|
||||
columns: [
|
||||
{
|
||||
id: 'id',
|
||||
title: Ox._('ID')
|
||||
},
|
||||
{
|
||||
id: 'index',
|
||||
title: Ox._('Index')
|
||||
},
|
||||
{
|
||||
format: function(value) {
|
||||
return Ox.encodeHTMLEntities(value);
|
||||
},
|
||||
id: 'title',
|
||||
title: Ox._('Title'),
|
||||
visible: true,
|
||||
width: 256
|
||||
},
|
||||
{
|
||||
format: function(value, data) {
|
||||
return data.width && data.height
|
||||
? data.width + ' × ' + data.height + ' px'
|
||||
: Ox._('unknown')
|
||||
},
|
||||
id: 'resolution',
|
||||
title: Ox._('Resolution'),
|
||||
align: 'right',
|
||||
visible: true,
|
||||
width: 128
|
||||
},
|
||||
{
|
||||
format: function(value) {
|
||||
return value ? Ox.formatDuration(value) : Ox._('unknown');
|
||||
},
|
||||
id: 'duration',
|
||||
title: Ox._('Duration'),
|
||||
align: 'right',
|
||||
visible: true,
|
||||
width: 128
|
||||
},
|
||||
{
|
||||
format: function(value) {
|
||||
return value ? Ox.formatValue(value, 'B') : Ox._('unknown');
|
||||
},
|
||||
id: 'size',
|
||||
title: Ox._('Size'),
|
||||
align: 'right',
|
||||
visible: true,
|
||||
width: 128
|
||||
},
|
||||
{
|
||||
id: 'width',
|
||||
title: Ox._('Width')
|
||||
},
|
||||
{
|
||||
id: 'height',
|
||||
title: Ox._('Height')
|
||||
}
|
||||
],
|
||||
columnsResizable: true,
|
||||
columnsVisible: true,
|
||||
items: options.items.map(function(value, index) {
|
||||
return Ox.extend(value, {index: index})
|
||||
}),
|
||||
scrollbarsVisible: true,
|
||||
sort: [{key: 'index', operator: '+'}],
|
||||
sortable: true
|
||||
}).css({
|
||||
height: '320px',
|
||||
width: '640px'
|
||||
});
|
||||
|
||||
var that = Ox.Dialog({
|
||||
buttons: [$button],
|
||||
closeButton: true,
|
||||
content: $list,
|
||||
height: 320,
|
||||
removeOnClose: true,
|
||||
title: Ox._('{0} Video Files', [Ox.toTitleCase(options.action)]),
|
||||
width: 640
|
||||
});
|
||||
|
||||
var $select = Ox.Select({
|
||||
items: [
|
||||
{
|
||||
id: 'one',
|
||||
title: Ox._(
|
||||
'Create one {0} with multiple parts',
|
||||
[pandora.site.itemName.singular.toLowerCase()]
|
||||
)
|
||||
},
|
||||
{
|
||||
id: 'multiple',
|
||||
title: Ox._(
|
||||
'Create multiple {0}',
|
||||
[pandora.site.itemName.plural.toLowerCase()]
|
||||
)
|
||||
}
|
||||
],
|
||||
width: 256
|
||||
}).css({
|
||||
display: options.items.length > 1 ? 'block' : 'none',
|
||||
margin: '4px'
|
||||
});
|
||||
$($select.find('.OxButton')[0]).css({margin: '-1px'});
|
||||
$button.parent().parent().append($select);
|
||||
|
||||
function importVideos(callback) {
|
||||
var id;
|
||||
Ox.serialForEach(options.items, function(item, index, items, callback) {
|
||||
var isNewItem = index == 0 || $select.value() == 'multiple';
|
||||
(isNewItem ? pandora.api.add : Ox.noop)({
|
||||
title: item.title
|
||||
}, function(result) {
|
||||
if (isNewItem) {
|
||||
id = result.data.id;
|
||||
}
|
||||
(isNewItem ? pandora.api.edit : Ox.noop)(Ox.extend(
|
||||
Ox.filter(item, function(value, key) {
|
||||
return key != 'title';
|
||||
}),
|
||||
{'id': id}
|
||||
), function(result) {
|
||||
pandora.api.addMediaUrl({
|
||||
url: item.url,
|
||||
item: id
|
||||
}, callback);
|
||||
});
|
||||
});
|
||||
}, callback);
|
||||
}
|
||||
|
||||
function uploadVideos(callback) {
|
||||
var id;
|
||||
Ox.serialForEach(options.items, function(item, index, items, callback) {
|
||||
var isNewItem = index == 0 || $select.value() == 'multiple';
|
||||
var title = items[$select.value() == 'one' ? 0 : index].title;
|
||||
(isNewItem ? pandora.api.add : Ox.noop)({
|
||||
title: title
|
||||
}, function(result) {
|
||||
if (isNewItem) {
|
||||
id = result.data.id;
|
||||
}
|
||||
pandora.uploadQueue.add(Ox.extend(item, {
|
||||
item: {
|
||||
id: id,
|
||||
title: title
|
||||
}
|
||||
}));
|
||||
callback();
|
||||
});
|
||||
}, callback);
|
||||
}
|
||||
|
||||
return that;
|
||||
|
||||
};
|
233
static/js/addItemDialog.js
Normal file
233
static/js/addItemDialog.js
Normal file
|
@ -0,0 +1,233 @@
|
|||
'use strict';
|
||||
|
||||
pandora.ui.addItemDialog = function(options) {
|
||||
options = options || {};
|
||||
|
||||
var input = '';
|
||||
|
||||
var selected = options.selected ? options.selected : 'upload';
|
||||
|
||||
var $button;
|
||||
|
||||
var $panel = Ox.TabPanel({
|
||||
content: function(id) {
|
||||
var $content = Ox.Element().css({padding: '8px'});
|
||||
var $input = Ox.Input({
|
||||
changeOnKeypress: true,
|
||||
disabled: id == 'upload',
|
||||
label: Ox._(id == 'add' ? 'Title' : id == 'upload' ? 'File': 'URL'),
|
||||
labelWidth: 64,
|
||||
placeholder: id == 'import' ? Ox._('YouTube, Vimeo, etc.') : '',
|
||||
width: 512
|
||||
}).css({
|
||||
margin: '8px'
|
||||
}).bindEvent({
|
||||
change: function(data) {
|
||||
$button.options({disabled: !data.value});
|
||||
input = data.value;
|
||||
}
|
||||
}).appendTo($content);
|
||||
return $content;
|
||||
},
|
||||
tabs: [
|
||||
{
|
||||
id: 'add',
|
||||
title: Ox._('Add {0}', [pandora.site.itemName.singular]),
|
||||
disabled: pandora.site.itemRequiresVideo,
|
||||
selected: selected == 'add'
|
||||
},
|
||||
{
|
||||
id: 'upload',
|
||||
title: Ox._('Upload Video Files'),
|
||||
selected: selected == 'upload'
|
||||
},
|
||||
{
|
||||
id: 'import',
|
||||
title: Ox._('Import Video Files'),
|
||||
disabled: !pandora.site.capabilities.canImportItems[pandora.user.level],
|
||||
selected: selected == 'import'
|
||||
}
|
||||
]
|
||||
}).bindEvent({
|
||||
change: function(data) {
|
||||
selected = data.selected;
|
||||
that.options({buttons: [createButton()]});
|
||||
}
|
||||
});
|
||||
|
||||
var $screen = Ox.LoadingScreen({
|
||||
size: 16
|
||||
});
|
||||
|
||||
var that = Ox.Dialog({
|
||||
buttons: [createButton()],
|
||||
closeButton: true,
|
||||
content: $panel,
|
||||
height: 72,
|
||||
removeOnClose: true,
|
||||
title: Ox._('Add {0}', [pandora.site.itemName.singular]),
|
||||
width: 544
|
||||
});
|
||||
|
||||
function createButton() {
|
||||
$button = Ox[selected == 'upload' ? 'FileButton' : 'Button']({
|
||||
disabled: selected != 'upload',
|
||||
id: selected,
|
||||
title: selected == 'add'
|
||||
? Ox._('Add {0} Without Video Files', [pandora.site.itemName.singular])
|
||||
: selected == 'upload' ? Ox._('Select Video Files')
|
||||
: Ox._('Import Video Files'),
|
||||
width: selected == 'add' ? 192 : 128
|
||||
}).bindEvent({
|
||||
click: function(data) {
|
||||
if (selected == 'add') {
|
||||
that.options({content: $screen.start()});
|
||||
$button.options({disabled: true});
|
||||
pandora.api.add({title: input}, function(result) {
|
||||
Ox.Request.clearCache('find');
|
||||
$screen.stop();
|
||||
that.close();
|
||||
pandora.UI.set({
|
||||
item: result.data.id,
|
||||
itemView: 'info'
|
||||
});
|
||||
});
|
||||
} else if (selected == 'upload' && data.files.length > 0) {
|
||||
that.options({content: $screen.start()});
|
||||
$button.options({disabled: true});
|
||||
Ox.serialMap(data.files, function(file, index, files, callback) {
|
||||
getFileInfo(file, function(info) {
|
||||
callback(Ox.extend(info, {file: file}));
|
||||
});
|
||||
}, onInfo);
|
||||
} else {
|
||||
that.options({content: $screen.start()});
|
||||
$button.options({disabled: true});
|
||||
pandora.api.getMediaUrlInfo({
|
||||
url: input
|
||||
}, function(result) {
|
||||
onInfo(result.data.items);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
return $button;
|
||||
}
|
||||
|
||||
function getFileInfo(file, callback) {
|
||||
Ox.oshash(file, function(oshash) {
|
||||
var $video = $('<video>'),
|
||||
url = URL.createObjectURL(file),
|
||||
info = {
|
||||
audio: [],
|
||||
direct: false,
|
||||
oshash: oshash,
|
||||
name: file.name,
|
||||
size: file.size,
|
||||
title: file.name.split('.').slice(0, -1).join('.'),
|
||||
video: []
|
||||
};
|
||||
$video.one('error', function(event) {
|
||||
callback(info);
|
||||
});
|
||||
$video.one('loadedmetadata', function(event) {
|
||||
info.duration = $video[0].duration;
|
||||
if ($video[0].videoHeight > 0) {
|
||||
info.width = $video[0].videoWidth;
|
||||
info.height = $video[0].videoHeight;
|
||||
}
|
||||
if (info.duration) {
|
||||
info.bitrate = info.size * 8 / info.duration / 1000;
|
||||
}
|
||||
callback(info);
|
||||
});
|
||||
$video[0].src = url;
|
||||
});
|
||||
}
|
||||
|
||||
function getVideoInfo(info) {
|
||||
var values = Ox.map(pandora.site.importMetadata, function(value, key) {
|
||||
var isArray = Ox.isArray(
|
||||
Ox.getObjectById(pandora.site.itemKeys, key).type
|
||||
);
|
||||
if (isArray && value == '{tags}') {
|
||||
value = info.tags;
|
||||
} else {
|
||||
[
|
||||
'date', 'description', 'id', 'tags',
|
||||
'title', 'uploader', 'url'
|
||||
].forEach(function(infoKey) {
|
||||
var infoValue = info[infoKey] || '';
|
||||
if (key == 'year' && infoKey == 'date') {
|
||||
infoValue = infoValue.substr(0, 4);
|
||||
}
|
||||
if (infoKey == 'tags') {
|
||||
infoValue = infoValue.join(', ');
|
||||
}
|
||||
value = value.replace(
|
||||
new RegExp('\{' + infoKey + '\}', 'g'), infoValue
|
||||
);
|
||||
});
|
||||
// For example: director -> uploader
|
||||
if (isArray) {
|
||||
value = [value];
|
||||
}
|
||||
}
|
||||
return value;
|
||||
});
|
||||
}
|
||||
|
||||
function onInfo(items) {
|
||||
// FIXME: what about pending/aborted uploads
|
||||
pandora.api.findMedia({
|
||||
keys: ['id', 'item', 'url'],
|
||||
query: {
|
||||
conditions: selected == 'upload' ? items.map(function(item) {
|
||||
return {key: 'oshash', operator: '==', value: item.oshash};
|
||||
}) : items.map(function(item) {
|
||||
return {key: 'url', operator: '==', value: item.url};
|
||||
}),
|
||||
operator: '|'
|
||||
}
|
||||
}, function(result) {
|
||||
if (result.data.items.length) {
|
||||
Ox.serialMap(result.data.items, function(item, index, items, callback) {
|
||||
pandora.api.get({
|
||||
id: item.item,
|
||||
keys: ['id', 'title']
|
||||
}, function(result) {
|
||||
callback(Ox.extend(item, {
|
||||
itemID: result.data.id,
|
||||
itemTitle: result.data.title
|
||||
}));
|
||||
})
|
||||
}, function(media) {
|
||||
media = media.map(function(media) {
|
||||
return Ox.extend(media, Ox.getObject(
|
||||
items,
|
||||
selected == 'upload' ? 'oshash' : 'url',
|
||||
media[selected == 'upload' ? 'id' : 'url']
|
||||
));
|
||||
});
|
||||
$screen.stop();
|
||||
that.close();
|
||||
pandora.ui.mediaExistsDialog({
|
||||
action: selected,
|
||||
media: media,
|
||||
items: items
|
||||
}).open();
|
||||
});
|
||||
} else {
|
||||
$screen.stop();
|
||||
that.close();
|
||||
pandora.ui.addFilesDialog({
|
||||
action: selected,
|
||||
items: items
|
||||
}).open();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return that;
|
||||
|
||||
};
|
|
@ -67,7 +67,11 @@ pandora.ui.allItems = function(section) {
|
|||
.css({opacity: canAddItems ? 1 : 0.25})
|
||||
.hide()
|
||||
.bindEvent({
|
||||
click: pandora.addItem
|
||||
click: function() {
|
||||
pandora.$ui.addItemDialog = pandora.ui.addItemDialog({
|
||||
selected: 'add'
|
||||
}).open();
|
||||
}
|
||||
})
|
||||
.appendTo(that);
|
||||
$buttons[1] = Ox.Button({
|
||||
|
@ -80,7 +84,9 @@ pandora.ui.allItems = function(section) {
|
|||
.hide()
|
||||
.bindEvent({
|
||||
click: function() {
|
||||
pandora.$ui.uploadVideoDialog = pandora.ui.uploadVideoDialog().open();
|
||||
pandora.$ui.addItemDialog = pandora.ui.addItemDialog({
|
||||
selected: 'upload'
|
||||
}).open();
|
||||
}
|
||||
})
|
||||
.appendTo(that);
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=javascript
|
||||
'use strict';
|
||||
|
||||
pandora.ui.deleteItemDialog = function(item) {
|
||||
|
||||
var that = pandora.ui.iconDialog({
|
||||
buttons: [
|
||||
Ox.Button({
|
||||
id: 'keep',
|
||||
title: Ox._('Keep {0}', [Ox._(pandora.site.itemName.singular)])
|
||||
}).bindEvent({
|
||||
click: function() {
|
||||
that.close();
|
||||
}
|
||||
}),
|
||||
Ox.Button({
|
||||
id: 'delete',
|
||||
title: Ox._('Delete {0}', [Ox._(pandora.site.itemName.singular)])
|
||||
}).bindEvent({
|
||||
click: function() {
|
||||
that.close();
|
||||
pandora.api.remove({
|
||||
id: item.id
|
||||
}, function(result) {
|
||||
Ox.Request.clearCache();
|
||||
pandora.UI.set({item: ''});
|
||||
});
|
||||
}
|
||||
})
|
||||
],
|
||||
content: Ox._('Are you sure you want to delete the {0} "{1}"?'
|
||||
+ '<br><br>All data will be removed.',
|
||||
[Ox._(pandora.site.itemName.singular), item.title]),
|
||||
keys: {enter: 'delete', escape: 'keep'},
|
||||
title: Ox._('Delete {0}', [Ox._(pandora.site.itemName.singular)])
|
||||
});
|
||||
|
||||
return that;
|
||||
|
||||
};
|
||||
|
55
static/js/deleteItemsDialog.js
Normal file
55
static/js/deleteItemsDialog.js
Normal file
|
@ -0,0 +1,55 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=javascript
|
||||
'use strict';
|
||||
|
||||
pandora.ui.deleteItemsDialog = function(options) {
|
||||
options = Ox.extend({
|
||||
items: []
|
||||
}, options || {});
|
||||
|
||||
var that = pandora.ui.iconDialog({
|
||||
buttons: [
|
||||
Ox.Button({
|
||||
id: 'keep',
|
||||
title: Ox._('Keep {0}', [Ox._(pandora.site.itemName[options.items.length == 1 ? 'singular':'plural'])])
|
||||
}).bindEvent({
|
||||
click: function() {
|
||||
that.close();
|
||||
}
|
||||
}),
|
||||
Ox.Button({
|
||||
id: 'delete',
|
||||
title: Ox._('Delete {0}', [Ox._(pandora.site.itemName[options.items.length == 1 ? 'singular':'plural'])])
|
||||
}).bindEvent({
|
||||
click: function() {
|
||||
that.close();
|
||||
Ox.serialForEach(options.items, function(item, index, items, callback) {
|
||||
pandora.api.remove({
|
||||
id: item.id
|
||||
}, function(result) {
|
||||
callback();
|
||||
});
|
||||
}, function() {
|
||||
Ox.Request.clearCache();
|
||||
if (pandora.user.ui.item) {
|
||||
pandora.UI.set({item: ''});
|
||||
} else {
|
||||
pandora.UI.set({listSelection: []});
|
||||
pandora.reloadList();
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
],
|
||||
content: options.items.length == 1 ? Ox._('Are you sure you want to delete the {0} "{1}"?'
|
||||
+ '<br><br>All data will be removed.',
|
||||
[Ox._(pandora.site.itemName.singular), options.items[0].title])
|
||||
: Ox._('Are you sure you want to delete {0} {1}?'
|
||||
+ '<br><br>All data will be removed.',
|
||||
[options.items.length, Ox._(pandora.site.itemName.plural)]),
|
||||
keys: {enter: 'delete', escape: 'keep'},
|
||||
title: Ox._('Delete {0}', [Ox._(pandora.site.itemName[options.items.length == 1 ? 'singular':'plural'])])
|
||||
});
|
||||
|
||||
return that;
|
||||
|
||||
};
|
12
static/js/editItemDialog.js
Normal file
12
static/js/editItemDialog.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
'use strict';
|
||||
|
||||
pandora.ui.editItemDialog = function() {
|
||||
var that = Ox.Dialog({
|
||||
closeButton: true,
|
||||
content: Ox.Element().html('HERE WILL BE DRAGONS').css({'text-align': 'center', 'margin-top': '16px'}),
|
||||
height: 72,
|
||||
title: Ox._('Edit {0}', [pandora.site.itemName.singular]),
|
||||
width: 544
|
||||
});
|
||||
return that;
|
||||
}
|
|
@ -64,7 +64,9 @@ pandora.ui.infoView = function(data) {
|
|||
if (data_.id == 'update') {
|
||||
updateMetadata();
|
||||
} else if (data_.id == 'delete') {
|
||||
pandora.$ui.deleteItemDialog = pandora.ui.deleteItemDialog(data).open();
|
||||
pandora.$ui.deleteItemsDialog = pandora.ui.deleteItemsDialog({
|
||||
items: [data]
|
||||
}).open();
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -91,9 +91,14 @@ pandora.ui.infoView = function(data) {
|
|||
} else if (data_.id == 'metadata') {
|
||||
pandora.$ui.metadataDialog = pandora.ui.metadataDialog(data).open();
|
||||
} else if (data_.id == 'upload') {
|
||||
pandora.$ui.uploadVideoDialog = pandora.ui.uploadVideoDialog(data).open();
|
||||
pandora.$ui.addItemDialog = pandora.ui.addItemDialog({
|
||||
item: pandora.user.ui.item,
|
||||
selected: 'upload'
|
||||
}).open();
|
||||
} else if (data_.id == 'delete') {
|
||||
pandora.$ui.deleteItemDialog = pandora.ui.deleteItemDialog(data).open();
|
||||
pandora.$ui.deleteItemsDialog = pandora.ui.deleteItemsDialog({
|
||||
items: [data]
|
||||
}).open();
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -61,7 +61,9 @@ pandora.ui.infoView = function(data) {
|
|||
.bindEvent({
|
||||
click: function(data_) {
|
||||
if (data_.id == 'delete') {
|
||||
pandora.$ui.deleteItemDialog = pandora.ui.deleteItemDialog(data).open();
|
||||
pandora.$ui.deleteItemsDialog = pandora.ui.deleteItemsDialog({
|
||||
items: [data]
|
||||
}).open();
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -61,7 +61,9 @@ pandora.ui.infoView = function(data) {
|
|||
.bindEvent({
|
||||
click: function(data_) {
|
||||
if (data_.id == 'delete') {
|
||||
pandora.$ui.deleteItemDialog = pandora.ui.deleteItemDialog(data).open();
|
||||
pandora.$ui.deleteItemsDialog = pandora.ui.deleteItemsDialog({
|
||||
items: [data]
|
||||
}).open();
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -85,7 +85,7 @@ pandora.ui.list = function() {
|
|||
//Ox.Log('', 'data, pandora.Query.toObject', data, pandora.Query.toObject())
|
||||
pandora.api.find(Ox.extend(data, {
|
||||
query: ui.find,
|
||||
keys: data.keys ? ['modified'].concat(data.keys) : void 0
|
||||
keys: data.keys ? ['editable', 'modified'].concat(data.keys) : void 0
|
||||
}), callback);
|
||||
return Ox.clone(data, true);
|
||||
},
|
||||
|
@ -165,7 +165,7 @@ pandora.ui.list = function() {
|
|||
}), callback);
|
||||
return Ox.clone(data, true);
|
||||
},
|
||||
keys: ['id', 'modified', 'posterRatio'].concat(pandora.site.itemTitleKeys),
|
||||
keys: ['id', 'editable', 'modified', 'posterRatio'].concat(pandora.site.itemTitleKeys),
|
||||
selected: ui.listSelection,
|
||||
size: 128,
|
||||
sort: ui.listSort,
|
||||
|
@ -241,7 +241,7 @@ pandora.ui.list = function() {
|
|||
});
|
||||
return Ox.clone(data, true);
|
||||
},
|
||||
keys: ['clips', 'duration', 'id', 'modified', 'posterRatio', 'videoRatio'].concat(pandora.site.itemTitleKeys),
|
||||
keys: ['clips', 'duration', 'editable', 'id', 'modified', 'posterRatio', 'videoRatio'].concat(pandora.site.itemTitleKeys),
|
||||
selected: ui.listSelection,
|
||||
size: 192,
|
||||
sort: ui.listSort,
|
||||
|
@ -358,7 +358,7 @@ pandora.ui.list = function() {
|
|||
}} : {})), callback);
|
||||
return Ox.clone(data, true);
|
||||
},
|
||||
keys: ['clips', 'duration', 'id', 'modified', 'posterRatio', 'rendered'].concat(pandora.site.itemTitleKeys),
|
||||
keys: ['clips', 'duration', 'editable', 'id', 'modified', 'posterRatio', 'rendered'].concat(pandora.site.itemTitleKeys),
|
||||
selected: ui.listSelection,
|
||||
size: 192,
|
||||
sort: ui.listSort,
|
||||
|
|
|
@ -13,7 +13,9 @@ pandora.ui.mainMenu = function() {
|
|||
lists = {},
|
||||
that = Ox.MainMenu({
|
||||
extras: pandora.site.menuExtras.map(function(menuExtra) {
|
||||
if (menuExtra == 'user') {
|
||||
if (menuExtra == 'upload') {
|
||||
return pandora.$ui.uploadButton = pandora.ui.uploadButton();
|
||||
} else if (menuExtra == 'user') {
|
||||
return pandora.$ui.userButton = pandora.ui.userButton();
|
||||
} else if (menuExtra == 'locale') {
|
||||
return pandora.$ui.localeButton = pandora.ui.localeButton();
|
||||
|
@ -42,6 +44,7 @@ pandora.ui.mainMenu = function() {
|
|||
{ id: 'username', title: Ox._('User: {0}', [isGuest ? 'not signed in' : Ox.encodeHTMLEntities(pandora.user.username)]), disabled: true },
|
||||
{},
|
||||
{ id: 'preferences', title: Ox._('Preferences...'), disabled: isGuest, keyboard: 'control ,' },
|
||||
{ id: 'tasks', title: Ox._('Tasks...'), disabled: isGuest },
|
||||
{ id: 'archives', title: Ox._('Archives...'), disabled: /*isGuest*/ true },
|
||||
{},
|
||||
{ id: 'signup', title: Ox._('Sign Up...'), disabled: !isGuest },
|
||||
|
@ -367,6 +370,8 @@ pandora.ui.mainMenu = function() {
|
|||
})
|
||||
), data.id)) {
|
||||
pandora.UI.set({page: data.id});
|
||||
} else if (data.id == 'tasks') {
|
||||
pandora.ui.tasksDialog().open();
|
||||
} else if (Ox.contains([
|
||||
'newlist', 'newlistfromselection', 'newsmartlist', 'newsmartlistfromresults'
|
||||
], data.id)) {
|
||||
|
@ -384,11 +389,9 @@ pandora.ui.mainMenu = function() {
|
|||
} else if (data.id == 'editlist') {
|
||||
pandora.ui.listDialog().open();
|
||||
} else if (data.id == 'add') {
|
||||
pandora.addItem();
|
||||
} else if (data.id == 'upload') {
|
||||
pandora.$ui.uploadVideoDialog = pandora.ui.uploadVideoDialog().open();
|
||||
} else if (data.id == 'import') {
|
||||
pandora.$ui.importMediaDialog = pandora.ui.importMediaDialog().open();
|
||||
pandora.$ui.addItemDialog = pandora.ui.addItemDialog().open();
|
||||
} else if (data.id == 'edit') {
|
||||
pandora.ui.editItemDialog().open();
|
||||
} else if (data.id == 'deletelist') {
|
||||
pandora.ui.deleteListDialog().open();
|
||||
} else if (data.id == 'print') {
|
||||
|
@ -465,10 +468,27 @@ pandora.ui.mainMenu = function() {
|
|||
pandora.clipboard.clear();
|
||||
} else if (data.id == 'delete') {
|
||||
if (ui.section == 'items') {
|
||||
pandora.doHistory('delete', ui.listSelection, ui._list, function() {
|
||||
pandora.UI.set({listSelection: []});
|
||||
pandora.reloadList();
|
||||
});
|
||||
if (ui._list) {
|
||||
pandora.doHistory('delete', ui.listSelection, ui._list, function() {
|
||||
pandora.UI.set({listSelection: []});
|
||||
pandora.reloadList();
|
||||
});
|
||||
} else {
|
||||
pandora.api.find({
|
||||
query: {
|
||||
conditions: ui.listSelection.map(function(id) {
|
||||
return {key: 'id', value: id, operator: '=='}
|
||||
}),
|
||||
operator: '|'
|
||||
},
|
||||
keys: ['id', 'title'],
|
||||
range: [0, ui.listSelection.length]
|
||||
}, function(result) {
|
||||
pandora.$ui.deleteItemsDialog = pandora.ui.deleteItemsDialog({
|
||||
items: result.data.items
|
||||
}).open();
|
||||
});
|
||||
}
|
||||
} else if (ui.section == 'edits') {
|
||||
var clips = pandora.$ui.editPanel.getSelectedClips();
|
||||
pandora.doHistory('delete', clips, ui.edit, function(result) {
|
||||
|
@ -987,6 +1007,7 @@ pandora.ui.mainMenu = function() {
|
|||
|
||||
function getItemMenu() {
|
||||
var listData = pandora.getListData(),
|
||||
deleteVerb = ui._list ? Ox._('Remove') : Ox._('Delete'),
|
||||
isEditable = listData.editable && listData.type == 'static',
|
||||
isClipView = pandora.isClipView()
|
||||
&& pandora.$ui.clipList
|
||||
|
@ -999,7 +1020,9 @@ pandora.ui.mainMenu = function() {
|
|||
isEditView = ui.section == 'edits' && ui.edit
|
||||
&& ui.editView != 'annotations', // FIXME: focus
|
||||
listName = isVideoView || isClipView ? ''
|
||||
: ui.section == 'items' ? Ox._('from List')
|
||||
: ui.section == 'items' ? (
|
||||
ui._list ? Ox._('from List') : Ox._('from Archive')
|
||||
)
|
||||
: Ox._('from Edit'),
|
||||
listItemsName = Ox._(
|
||||
ui.section == 'edits' || isVideoView || isClipView ? 'Clips'
|
||||
|
@ -1026,6 +1049,24 @@ pandora.ui.mainMenu = function() {
|
|||
: clipboardType == 'clip' ? (clipboardItems == 1 ? 'Clip' : 'Clips')
|
||||
: ''
|
||||
),
|
||||
canEdit = pandora.site.capabilities.canEditMedia[pandora.user.level] || (
|
||||
ui.section == 'items' && (
|
||||
ui.item || (
|
||||
Ox.contains(['list', 'grid', 'clips', 'timelines'], ui.listView)
|
||||
&& ui.listSelection.length == 1
|
||||
)
|
||||
) && pandora.$ui.list.value(ui.listSelection[0], 'editable')
|
||||
),
|
||||
canDelete = pandora.site.capabilities.canRemoveItems[pandora.user.level] || (
|
||||
ui.section == 'items' && (
|
||||
ui.item || (
|
||||
Ox.contains(['list', 'grid', 'clips', 'timelines'], ui.listView)
|
||||
&& ui.listSelection.length
|
||||
)
|
||||
) && ui.listSelection.every(function(item) {
|
||||
return pandora.$ui.list.value(item, 'editable');
|
||||
})
|
||||
),
|
||||
canSelect = isListView || isClipView || isEditView,
|
||||
canCopy = isListView ? ui.listSelection.length
|
||||
: isClipView ? pandora.$ui.clipList.options('selected').length
|
||||
|
@ -1042,9 +1083,8 @@ pandora.ui.mainMenu = function() {
|
|||
undoText = pandora.history.undoText(),
|
||||
redoText = pandora.history.redoText();
|
||||
return { id: 'itemMenu', title: Ox._('Item'), items: [
|
||||
{ id: 'add', title: Ox._('Add {0}', [Ox._(pandora.site.itemName.singular)]), disabled: pandora.site.itemRequiresVideo || !pandora.site.capabilities.canAddItems[pandora.user.level] },
|
||||
{ id: 'upload', title: Ox._('Upload Video...'), disabled: !pandora.site.capabilities.canAddItems[pandora.user.level] },
|
||||
{ id: 'import', title: Ox._('Import Video...'), disabled: !pandora.site.capabilities.canImportItems[pandora.user.level] },
|
||||
{ id: 'add', title: Ox._('Add {0}...', [Ox._(pandora.site.itemName.singular)]), disabled: !pandora.site.capabilities.canAddItems[pandora.user.level] },
|
||||
{ id: 'edit', title: Ox._('Edit {0}...', [Ox._(pandora.site.itemName.singular)]), disabled: true /*fixme: !canEdit */ },
|
||||
{},
|
||||
{ id: 'selectall', title: Ox._('Select All {0}', [listItemsName]), disabled: !canSelect, keyboard: 'control a' },
|
||||
{ id: 'selectnone', title: Ox._('Select None'), disabled: !canSelect, keyboard: 'shift control a' },
|
||||
|
@ -1057,7 +1097,7 @@ pandora.ui.mainMenu = function() {
|
|||
{ id: 'paste', title: clipboardItems == 0 ? Ox._('Paste') : Ox._('Paste {0}', [clipboardItemName]), disabled: !canPaste, keyboard: 'control v' },
|
||||
{ id: 'clearclipboard', title: Ox._('Clear Clipboard'), disabled: !clipboardItems},
|
||||
{},
|
||||
{ id: 'delete', title: Ox._('Delete {0} {1}', [selectionItemName, listName]), disabled: !canCut, keyboard: 'delete' },
|
||||
{ id: 'delete', title: Ox._('{0} {1} {2}', [deleteVerb, selectionItemName, listName]), disabled: !canDelete, keyboard: 'delete' },
|
||||
{},
|
||||
{ id: 'undo', title: undoText ? Ox._('Undo {0}', [undoText]) : Ox._('Undo'), disabled: !undoText, keyboard: 'control z' },
|
||||
{ id: 'redo', title: redoText ? Ox._('Redo {0}', [redoText]) : Ox._('Redo'), disabled: !redoText, keyboard: 'shift control z' },
|
||||
|
|
80
static/js/mediaExistsDialog.js
Normal file
80
static/js/mediaExistsDialog.js
Normal file
|
@ -0,0 +1,80 @@
|
|||
'use strict';
|
||||
|
||||
pandora.ui.mediaExistsDialog = function(options) {
|
||||
|
||||
var title = options.media.length == 1 ? 'File Exists' : 'Files Exist';
|
||||
|
||||
var $content = Ox.Element().addClass('OxText').css({
|
||||
margin: '16px',
|
||||
overflow: 'auto'
|
||||
}).html(
|
||||
'<p>' + (
|
||||
options.media.length == 1 && options.items.length == 1
|
||||
? Ox._('The video file already exists:')
|
||||
: options.media.length == options.items.length
|
||||
? Ox._(
|
||||
'All {0} video files already exist:',
|
||||
[options.media.length]
|
||||
)
|
||||
: Ox._(
|
||||
'{0} of the {1} video files already exist:',
|
||||
[options.media.length, options.items.length])
|
||||
) + '</p>' + options.media.map(function(media) {
|
||||
return media[options.action == 'upload' ? 'name' : 'title']
|
||||
+ ': <a href="/' + media.itemID + '" target="_blank">'
|
||||
+ media.itemTitle + '</a>';
|
||||
}).join('<br/>')
|
||||
)
|
||||
|
||||
var $buttons = options.media.length == options.items.length ? [
|
||||
Ox.Button({
|
||||
id: 'close',
|
||||
title: Ox._('Close')
|
||||
}).bindEvent({
|
||||
click: function() {
|
||||
that.close();
|
||||
}
|
||||
})
|
||||
] : [
|
||||
Ox.Button({
|
||||
id: 'cancel',
|
||||
title: Ox._('Don\'t {0}', [Ox.toTitleCase(options.action)])
|
||||
}).bindEvent({
|
||||
click: function() {
|
||||
that.close();
|
||||
}
|
||||
}),
|
||||
Ox.Button({
|
||||
id: 'continue',
|
||||
title: Ox._(Ox.toTitleCase(options.action)) + ' '
|
||||
+ (options.items.length - options.media.length) + ' '
|
||||
+ Ox._(options.items.length - options.media.length == 1 ? 'File' : 'Files')
|
||||
}).bindEvent({
|
||||
click: function() {
|
||||
var existing = options.media.map(function(item) {
|
||||
return item.id;
|
||||
}),
|
||||
items = options.items.filter(function(item) {
|
||||
return existing.indexOf(item.oshash) == -1;
|
||||
});
|
||||
pandora.ui.addFilesDialog({
|
||||
action: options.action,
|
||||
items: items
|
||||
}).open();
|
||||
}
|
||||
})
|
||||
];
|
||||
|
||||
var that = Ox.Dialog({
|
||||
buttons: $buttons,
|
||||
closeButton: true,
|
||||
content: $content,
|
||||
height: 256,
|
||||
removeOnClose: true,
|
||||
title: title,
|
||||
width: 512,
|
||||
});
|
||||
|
||||
return that;
|
||||
|
||||
};
|
|
@ -518,7 +518,9 @@ pandora.ui.mediaView = function(options) {
|
|||
id: pandora.user.ui.item,
|
||||
keys: ['id', 'title']
|
||||
},function(result) {
|
||||
pandora.ui.deleteItemDialog(result.data).open();
|
||||
pandora.$ui.deleteItemsDialog = pandora.ui.deleteItemsDialog({
|
||||
items: [result.data]
|
||||
}).open();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
'use strict';
|
||||
|
||||
pandora.ui.tasksDialog = function() {
|
||||
pandora.ui.tasksDialog = function(options) {
|
||||
options = Ox.extend({
|
||||
tasks: 'all'
|
||||
}, options || {});
|
||||
|
||||
var canceling = [],
|
||||
|
||||
timeout,
|
||||
clientItems = [], serverItems = [], listItems = [],
|
||||
|
||||
clientTimeout, serverTimeout,
|
||||
|
||||
$list = Ox.TableList({
|
||||
columns: [
|
||||
|
@ -13,6 +18,16 @@ pandora.ui.tasksDialog = function() {
|
|||
title: Ox._('ID'),
|
||||
visible: false
|
||||
},
|
||||
{
|
||||
format: function(value) {
|
||||
return Ox.encodeHTMLEntities(value);
|
||||
},
|
||||
id: 'user',
|
||||
operator: '+',
|
||||
title: Ox._('User'),
|
||||
visible: false,
|
||||
width: 144
|
||||
},
|
||||
{
|
||||
format: function(value) {
|
||||
return Ox.encodeHTMLEntities(value);
|
||||
|
@ -21,7 +36,7 @@ pandora.ui.tasksDialog = function() {
|
|||
operator: '+',
|
||||
title: Ox._('Title'),
|
||||
visible: true,
|
||||
width: 256
|
||||
width: 288
|
||||
},
|
||||
{
|
||||
format: function(value) {
|
||||
|
@ -49,62 +64,129 @@ pandora.ui.tasksDialog = function() {
|
|||
width: 144
|
||||
},
|
||||
{
|
||||
format: function(value) {
|
||||
return Ox.toTitleCase(value);
|
||||
format: function(value, data) {
|
||||
return {
|
||||
'pending': 'Uploading (Queued)',
|
||||
'uploading': 'Uploading' + (
|
||||
data.progress === void 0 ? '' : ' (' + (
|
||||
data.progress === 0 ? 'Queued'
|
||||
: data.progress + '%'
|
||||
) + ')'
|
||||
),
|
||||
'queued': $tasksSelect.value() == 'all'
|
||||
? 'Processing (Queued)'
|
||||
: 'Finished',
|
||||
'processing': 'Processing',
|
||||
'canceled': 'Canceled',
|
||||
'failed': 'Failed',
|
||||
'finished': 'Finished'
|
||||
}[value] || value;
|
||||
},
|
||||
id: 'status',
|
||||
operator: '+',
|
||||
sort: function(value) {
|
||||
return [
|
||||
'queued', 'uploading', 'importing', 'processing',
|
||||
'pending', 'uploading', 'queued', 'processing',
|
||||
'canceled', 'failed', 'finished'
|
||||
].indexOf(value);
|
||||
},
|
||||
title: Ox._('Status'),
|
||||
visible: true,
|
||||
width: 96
|
||||
width: 176
|
||||
},
|
||||
{
|
||||
id: 'progress',
|
||||
title: Ox._('Progress'),
|
||||
visible: false
|
||||
}
|
||||
|
||||
],
|
||||
columnsVisible: true,
|
||||
items: [],
|
||||
items: listItems,
|
||||
sort: [{key: 'ended', operator: '-'}],
|
||||
unique: 'id'
|
||||
}).bindEvent({
|
||||
select: updateButton
|
||||
select: updateButton,
|
||||
open: function(data) {
|
||||
var item;
|
||||
if (data.ids.length == 1) {
|
||||
item = listItems.filter(function(item) {
|
||||
return item.id == data.ids[0];
|
||||
})[0];
|
||||
if (item && item.item) {
|
||||
that.close();
|
||||
pandora.UI.set({
|
||||
item: item.item,
|
||||
itemView: 'info'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
$sidebar = Ox.Element().css({
|
||||
margin: '4px'
|
||||
}),
|
||||
|
||||
$checkbox = Ox.Checkbox({
|
||||
title: Ox._('Show All Tasks')
|
||||
$tasksSelect = Ox.Select({
|
||||
items: [
|
||||
{id: 'uploads', title: Ox._('Show Uploads')},
|
||||
{id: 'all', title: Ox._('Show All Tasks')}
|
||||
],
|
||||
value: options.tasks,
|
||||
width: 128
|
||||
}).css({
|
||||
display: true || pandora.site.capabilities.canSeeAllTasks[
|
||||
pandora.user.level
|
||||
] ? 'block' : 'none',
|
||||
margin: '4px'
|
||||
}).bindEvent({
|
||||
change: getItems
|
||||
change: updateList
|
||||
})
|
||||
.appendTo($sidebar),
|
||||
|
||||
$usersSelect = Ox.Select({
|
||||
items: [
|
||||
{id: 'my', title: Ox._('Show My Tasks')},
|
||||
{id: 'all', title: Ox._('Show All Users')}
|
||||
],
|
||||
width: 128
|
||||
}).css({
|
||||
display: pandora.site.capabilities.canSeeAllTasks[
|
||||
pandora.user.level
|
||||
] ? 'block' : 'none',
|
||||
margin: '8px 4px 4px 4px'
|
||||
}).bindEvent({
|
||||
change: function(data) {
|
||||
$list[data.value == 'all' ? 'addColumn' : 'removeColumn']('user');
|
||||
$list.resizeColumn('title', data.value == 'all' ? 144 : 288);
|
||||
setTimeout(updateList);
|
||||
}
|
||||
})
|
||||
.appendTo($sidebar),
|
||||
|
||||
$button = Ox.Button({
|
||||
disabled: true,
|
||||
title: Ox._('Cancel Task'),
|
||||
width: 112
|
||||
width: 128
|
||||
}).css({
|
||||
margin: '4px',
|
||||
}).bindEvent({
|
||||
click: function() {
|
||||
$button.options({disabled: true});
|
||||
var ids = $list.options('selected').filter(canBeCanceled);
|
||||
canceling.push(ids);
|
||||
$button.options({disabled: true});
|
||||
ids.forEach(function(id) {
|
||||
if (Ox.contains(
|
||||
['pending', 'uploading'], $list.value(id, 'status')
|
||||
)) {
|
||||
pandora.uploadQueue.remove(id);
|
||||
}
|
||||
})
|
||||
pandora.api.cancelTask({
|
||||
id: ids
|
||||
}, function() {
|
||||
canceling = [];
|
||||
getItems();
|
||||
canceling = canceling.filter(function(id) {
|
||||
return !Ox.contains(ids, id);
|
||||
});
|
||||
getServerItems();
|
||||
});
|
||||
}
|
||||
}).appendTo($sidebar),
|
||||
|
@ -113,7 +195,7 @@ pandora.ui.tasksDialog = function() {
|
|||
elements: [
|
||||
{
|
||||
element: $list,
|
||||
size: 640
|
||||
size: 752
|
||||
},
|
||||
{
|
||||
element: $sidebar,
|
||||
|
@ -137,13 +219,16 @@ pandora.ui.tasksDialog = function() {
|
|||
content: $panel,
|
||||
height: 384,
|
||||
title: Ox._('Tasks'),
|
||||
width: 768
|
||||
width: 896
|
||||
})
|
||||
.bindEvent({
|
||||
close: function() {
|
||||
clearTimeout(timeout);
|
||||
clientTimeout && clearTimeout(clientTimeout);
|
||||
},
|
||||
open: getItems
|
||||
open: function() {
|
||||
getClientItems();
|
||||
getServerItems();
|
||||
}
|
||||
});
|
||||
|
||||
function canBeCanceled(id) {
|
||||
|
@ -153,15 +238,77 @@ pandora.ui.tasksDialog = function() {
|
|||
) && !Ox.contains(canceling, id);
|
||||
}
|
||||
|
||||
function getItems() {
|
||||
clearTimeout(timeout);
|
||||
pandora.api.getTasks($checkbox.value() ? {} : {
|
||||
function getClientItems(callback) {
|
||||
clearTimeout(clientTimeout);
|
||||
var uploads = pandora.uploadQueue.get();
|
||||
var uploadsById = {};
|
||||
uploads.forEach(function(upload) {
|
||||
uploadsById[upload.item.id] = (
|
||||
uploadsById[upload.item.id] || []
|
||||
).concat(upload);
|
||||
});
|
||||
clientItems = []
|
||||
Ox.forEach(uploadsById, function(uploads, id) {
|
||||
// FIXME: include upload.file.size
|
||||
var progress = Math.round(Ox.sum(uploads.map(function(upload) {
|
||||
return upload.data.progress / uploads.length;
|
||||
})) * 100);
|
||||
var status = uploads.map(function(upload) {
|
||||
return upload.data.status;
|
||||
});
|
||||
clientItems.push({
|
||||
ended: uploads.every(function(upload) {
|
||||
return upload.data.ended;
|
||||
}) ? Ox.max(uploads.map(function(upload) {
|
||||
return upload.data.ended;
|
||||
})) : '',
|
||||
id: id,
|
||||
progress: progress,
|
||||
started: Ox.min(uploads.map(function(upload) {
|
||||
return upload.data.started;
|
||||
})),
|
||||
status: Ox.contains(status, 'uploading') ? 'uploading'
|
||||
: Ox.contains(status, 'pending') ? 'pending'
|
||||
: Ox.contains(status, 'canceled') ? 'canceled'
|
||||
: 'queued',
|
||||
title: uploads[0].item.title,
|
||||
user: pandora.user.username
|
||||
});
|
||||
});
|
||||
clientTimeout = setTimeout(getClientItems, 1000);
|
||||
updateValues();
|
||||
callback && callback();
|
||||
}
|
||||
|
||||
function getListItems() {
|
||||
var allTasks = $tasksSelect.value() == 'all',
|
||||
uploading = allTasks
|
||||
? ['pending', 'uploading']
|
||||
: ['pending', 'uploading', 'queued'],
|
||||
items = clientItems.filter(function(item) {
|
||||
return Ox.contains(uploading, item.status);
|
||||
}),
|
||||
items = serverItems.filter(function(item) {
|
||||
return allTasks ? (
|
||||
Ox.getIndex(items, 'id', item.item) == -1
|
||||
|| item.user != pandora.user.username
|
||||
) : (
|
||||
Ox.getIndex(items, 'id', item.item) == -1
|
||||
&& Ox.getIndex(clientItems, 'id', item.item) > -1
|
||||
);
|
||||
}).concat(items);
|
||||
return items;
|
||||
}
|
||||
|
||||
function getServerItems(callback) {
|
||||
clearTimeout(serverTimeout);
|
||||
pandora.api.getTasks($usersSelect.value() == 'all' ? {} : {
|
||||
user: pandora.user.username
|
||||
}, function(result) {
|
||||
$list.options({items: result.data.items})
|
||||
updateButton()
|
||||
serverItems = result.data.items;
|
||||
serverTimeout = setTimeout(getServerItems, 10000);
|
||||
getClientItems(callback);
|
||||
});
|
||||
timeout = setTimeout(getItems, 15000);
|
||||
}
|
||||
|
||||
function updateButton() {
|
||||
|
@ -172,6 +319,31 @@ pandora.ui.tasksDialog = function() {
|
|||
});
|
||||
}
|
||||
|
||||
function updateList() {
|
||||
getServerItems(function() {
|
||||
listItems= getListItems();
|
||||
$list.options({items: listItems});
|
||||
updateButton();
|
||||
});
|
||||
}
|
||||
|
||||
function updateValues() {
|
||||
var currentListItems = getListItems(),
|
||||
hasNewItems = currentListItems.length != listItems.length;
|
||||
!hasNewItems && currentListItems.forEach(function(item) {
|
||||
if (Ox.getIndexById(listItems, item.id) == -1) {
|
||||
hasNewItems = true;
|
||||
} else if (!hasNewItems) {
|
||||
$list.value(item.id, 'progress', item.progress);
|
||||
$list.value(item.id, 'status', item.status);
|
||||
if (item.ended) {
|
||||
$list.value(item.id, 'ended', item.ended);
|
||||
}
|
||||
}
|
||||
});
|
||||
hasNewItems && updateList();
|
||||
}
|
||||
|
||||
return that;
|
||||
|
||||
};
|
||||
|
|
27
static/js/uploadButton.js
Normal file
27
static/js/uploadButton.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
'use strict';
|
||||
|
||||
pandora.ui.uploadButton = function() {
|
||||
|
||||
var that = Ox.Button({
|
||||
style: 'symbol',
|
||||
title: 'upload',
|
||||
type: 'image'
|
||||
}).css({
|
||||
display: 'none'
|
||||
}).bindEvent({
|
||||
click: function() {
|
||||
pandora.ui.tasksDialog({
|
||||
tasks: 'uploads'
|
||||
}).open();
|
||||
}
|
||||
});
|
||||
|
||||
that.update = function() {
|
||||
that.css({
|
||||
display: pandora.uploadQueue.uploading ? 'block' : 'none'
|
||||
});
|
||||
};
|
||||
|
||||
return that;
|
||||
|
||||
};
|
|
@ -2,13 +2,15 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
pandora.addItem = function() {
|
||||
pandora.api.add(function(result) {
|
||||
pandora.addItem = function(title, callback) {
|
||||
// unused
|
||||
pandora.api.add({title: title || 'Untitled'}, function(result) {
|
||||
Ox.Request.clearCache('find');
|
||||
pandora.UI.set({
|
||||
item: result.data.id,
|
||||
itemView: 'info'
|
||||
});
|
||||
callback && callback();
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -257,6 +259,12 @@ pandora.beforeUnloadWindow = function() {
|
|||
+ 'Are you sure that you want to leave this page?'
|
||||
);
|
||||
}
|
||||
if (pandora.uploadQueue.uploading) {
|
||||
return Ox._(
|
||||
'You still have active uploads. '
|
||||
+ 'Are you sure that you want to leave this page?'
|
||||
);
|
||||
}
|
||||
// Prevent error dialogs on unload
|
||||
pandora.isUnloading = true;
|
||||
};
|
||||
|
@ -2272,9 +2280,11 @@ pandora.reloadList = function() {
|
|||
// (but then it's also unlikely they'll have to be reloaded)
|
||||
var folder = listData.status != 'featured'
|
||||
? 'personal' : 'featured';
|
||||
pandora.$ui.folderList[folder].value(
|
||||
listData.id, 'items', data.items
|
||||
);
|
||||
if (!Ox.isEmpty(listData)) {
|
||||
pandora.$ui.folderList[folder].value(
|
||||
listData.id, 'items', data.items
|
||||
);
|
||||
}
|
||||
}
|
||||
})
|
||||
.bindEventOnce({
|
||||
|
@ -2639,12 +2649,89 @@ pandora.updateStatus = function(item) {
|
|||
return ui.item == item && [
|
||||
'info', 'player', 'editor', 'timeline'
|
||||
].indexOf(ui.itemView) > -1 && !(
|
||||
// fixme: still wrong
|
||||
pandora.$ui.uploadVideoDialog
|
||||
&& pandora.$ui.uploadVideoDialog.is('::visible')
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
pandora.uploadQueue = (function() {
|
||||
var that = {
|
||||
uploading: false
|
||||
};
|
||||
var queue = [];
|
||||
var index = -1;
|
||||
var uploader;
|
||||
|
||||
function upload() {
|
||||
if (index == queue.length - 1) {
|
||||
that.uploading = false;
|
||||
pandora.$ui.uploadButton && pandora.$ui.uploadButton.update();
|
||||
return;
|
||||
}
|
||||
index++;
|
||||
if (queue[index].data.status == 'canceled') {
|
||||
upload();
|
||||
return;
|
||||
}
|
||||
that.uploading = true;
|
||||
queue[index].data.status = 'uploading';
|
||||
pandora.$ui.uploadButton && pandora.$ui.uploadButton.update();
|
||||
pandora.api.addMedia({
|
||||
filename: queue[index].file.name,
|
||||
id: queue[index].oshash,
|
||||
item: queue[index].item.id
|
||||
}, function(result) {
|
||||
uploader = pandora.chunkupload({
|
||||
data: {id: queue[index].oshash},
|
||||
file: queue[index].file,
|
||||
url: '/api/upload/direct/'
|
||||
}).bindEvent({
|
||||
done: function(data) {
|
||||
queue[index].data.ended = +new Date();
|
||||
queue[index].data.status = data.progress == 1 ? 'queued' : 'failed';
|
||||
queue[index].data.progress = data.progress;
|
||||
upload();
|
||||
},
|
||||
progress: function(data) {
|
||||
queue[index].data.progress = data.progress;
|
||||
}
|
||||
});
|
||||
that.uploading = queue[index].item.id;
|
||||
});
|
||||
}
|
||||
that.add = function(items) {
|
||||
items = Ox.isArray(items) ? items : [items];
|
||||
queue = queue.concat(items.map(function(item) {
|
||||
return Ox.extend(item, {
|
||||
data: {
|
||||
progress: 0,
|
||||
started: +new Date(),
|
||||
status: 'pending'
|
||||
}
|
||||
});
|
||||
}));
|
||||
!that.uploading && upload();
|
||||
};
|
||||
that.get = function() {
|
||||
return queue;
|
||||
};
|
||||
that.remove = function(id) {
|
||||
queue.forEach(function(item, index) {
|
||||
if (item.item.id == id) {
|
||||
queue[index].data.status = 'canceled';
|
||||
}
|
||||
});
|
||||
if (that.uploading == id) {
|
||||
uploader.abort();
|
||||
upload();
|
||||
}
|
||||
};
|
||||
|
||||
return that;
|
||||
}());
|
||||
|
||||
pandora.wait = function(id, callback, timeout) {
|
||||
var task = {};
|
||||
timeout = timeout || 5000;
|
||||
|
|
Loading…
Reference in a new issue