forked from 0x2620/pandora
adding iconList and mapView
This commit is contained in:
parent
9626995fd4
commit
e5e82bf886
9 changed files with 496 additions and 491 deletions
|
@ -544,6 +544,7 @@
|
|||
"preferences": {},
|
||||
"ui": {
|
||||
"annotationsSize": 256,
|
||||
"clipsColumns": 1,
|
||||
"columns": {
|
||||
"Colors": {
|
||||
"columns": ["title", "director", "country", "year", "hue", "saturation", "brightness"],
|
||||
|
|
176
static/js/pandora/ui/clipList.js
Normal file
176
static/js/pandora/ui/clipList.js
Normal file
|
@ -0,0 +1,176 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=javascript
|
||||
|
||||
pandora.ui.clipList = function(videoRatio) {
|
||||
|
||||
var ui = pandora.user.ui,
|
||||
fixedRatio = !ui.item ? 16/9 : videoRatio,
|
||||
isClipView = !ui.item ? ui.listView == 'clip' : ui.itemView == 'clips',
|
||||
|
||||
that = Ox.IconList({
|
||||
fixedRatio: fixedRatio,
|
||||
item: function(data, sort, size) {
|
||||
size = size || 128; // fixme: is this needed?
|
||||
var ratio, width, height, url, sortKey, info;
|
||||
if (!ui.item) {
|
||||
ratio = data.videoRatio;
|
||||
width = ratio > fixedRatio ? size : Math.round(size * ratio / fixedRatio);
|
||||
height = Math.round(width / ratio);
|
||||
} else {
|
||||
width = fixedRatio > 1 ? size : Math.round(size * fixedRatio);
|
||||
height = fixedRatio > 1 ? Math.round(size / fixedRatio) : size;
|
||||
}
|
||||
url = '/' + data.id.split('/')[0] + '/' + height + 'p' + data['in'] + '.jpg';
|
||||
sortKey = sort[0].key.split(':').pop();
|
||||
info = ['hue', 'saturation', 'lightness'].indexOf(sortKey) > -1
|
||||
? Ox.formatColor(data[sortKey], sortKey)
|
||||
: Ox.formatDuration(data['in'], 'short') + ' - '
|
||||
+ Ox.formatDuration(data['out'], 'short');
|
||||
return {
|
||||
height: height,
|
||||
id: data.id,
|
||||
info: info,
|
||||
title: data.value,
|
||||
url: url,
|
||||
width: width
|
||||
};
|
||||
},
|
||||
items: isClipView ? function(data, callback) {
|
||||
var itemQuery, query;
|
||||
if (!ui.item) {
|
||||
itemQuery = ui.find;
|
||||
query = {conditions: [], operator: '&'};
|
||||
// if the item query contains a layer condition,
|
||||
// then this condition is added to the clip query
|
||||
// fixme: don't just check for 'subtitles'
|
||||
itemQuery.conditions.forEach(function(condition) {
|
||||
if (condition.key == 'subtitles') {
|
||||
query.conditions.push({
|
||||
key: 'value',
|
||||
value: condition.value,
|
||||
operator: condition.operator
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
itemQuery = {
|
||||
conditions:[{key: 'id', value: ui.item, operator: '=='}],
|
||||
operator: '&'
|
||||
};
|
||||
// fixme: there is currently no way to add a clip query
|
||||
// we'll need something like itemFind (vs. listFind)
|
||||
query = {conditions: [], operator: '&'};
|
||||
}
|
||||
pandora.api.findAnnotations(Ox.extend({
|
||||
itemQuery: itemQuery,
|
||||
query: query
|
||||
}, data), callback);
|
||||
} : [],
|
||||
keys: Ox.merge(
|
||||
['id', 'in', 'out', 'value'],
|
||||
!ui.item ? ['videoRatio'] : []
|
||||
),
|
||||
max: 1,
|
||||
orientation: 'both',
|
||||
size: 128,
|
||||
sort: !ui.item ? ui.listSort : ui.itemSort,
|
||||
unique: 'id'
|
||||
})
|
||||
.bindEvent({
|
||||
init: function(data) {
|
||||
// fixme: status needs an overhaul
|
||||
if (!ui.item) {
|
||||
pandora.$ui.total.html(pandora.ui.status('total', data));
|
||||
}
|
||||
},
|
||||
open: function(data) {
|
||||
var id = data.ids[0],
|
||||
item = !ui.item ? id.split('/')[0] : ui.item,
|
||||
points = {
|
||||
'in': that.value(id, 'in'),
|
||||
out: that.value(id, 'out')
|
||||
},
|
||||
set = {
|
||||
item: item,
|
||||
itemView: pandora.user.ui.videoView
|
||||
};
|
||||
set['videoPoints.' + item] = Ox.extend(points, {
|
||||
position: points['in']
|
||||
});
|
||||
pandora.UI.set(set);
|
||||
},
|
||||
openpreview: function(data) {
|
||||
// on press space key
|
||||
var $video = that.find('.OxItem.OxSelected > .OxIcon > .OxVideoPlayer');
|
||||
if ($video) {
|
||||
// trigger singleclick
|
||||
$video.trigger('mousedown');
|
||||
Ox.UI.$window.trigger('mouseup');
|
||||
}
|
||||
that.closePreview();
|
||||
},
|
||||
select: function(data) {
|
||||
if (data.ids.length) {
|
||||
var id = data.ids[0],
|
||||
item = id.split('/')[0], width, height,
|
||||
$img = that.find('.OxItem.OxSelected > .OxIcon > img'),
|
||||
$video = that.find('.OxItem.OxSelected > .OxIcon > .OxVideoPlayer'),
|
||||
size = 128, ratio, width, height;
|
||||
if ($img.length) {
|
||||
if (!ui.item) {
|
||||
ratio = that.value(id, 'videoRatio');
|
||||
width = ratio > fixedRatio ? size : Math.round(size * ratio / fixedRatio);
|
||||
height = Math.round(width / ratio);
|
||||
} else {
|
||||
width = fixedRatio > 1 ? size : Math.round(size * fixedRatio);
|
||||
height = fixedRatio > 1 ? Math.round(size / fixedRatio) : size;
|
||||
}
|
||||
pandora.api.get({id: item, keys: ['durations']}, function(result) {
|
||||
var points = [that.value(id, 'in'), that.value(id, 'out')],
|
||||
partsAndPoints = pandora.getVideoPartsAndPoints(
|
||||
result.data.durations, points
|
||||
),
|
||||
$player = Ox.VideoPlayer({
|
||||
height: height,
|
||||
'in': partsAndPoints.points[0],
|
||||
out: partsAndPoints.points[1],
|
||||
paused: true,
|
||||
playInToOut: true,
|
||||
poster: '/' + item + '/' + height + 'p' + points[0] + '.jpg',
|
||||
width: width,
|
||||
video: partsAndPoints.parts.map(function(i) {
|
||||
return '/' + item + '/96p' + (i + 1)
|
||||
+ '.' + pandora.user.videoFormat;
|
||||
})
|
||||
})
|
||||
.addClass('OxTarget')
|
||||
.bindEvent({
|
||||
// doubleclick opens item
|
||||
singleclick: function() {
|
||||
$player.$element.is('.OxSelectedVideo')&& $player.togglePaused();
|
||||
}
|
||||
});
|
||||
$img.replaceWith($player.$element);
|
||||
$('.OxSelectedVideo').removeClass('OxSelectedVideo');
|
||||
$player.$element.addClass('OxSelectedVideo');
|
||||
});
|
||||
} else if ($video.length) {
|
||||
// item select fires before video click
|
||||
// so we have to make sure that selecting
|
||||
// an item that already has a video
|
||||
// doesn't click through to play
|
||||
setTimeout(function() {
|
||||
$('.OxSelectedVideo').removeClass('OxSelectedVideo');
|
||||
$video.addClass('OxSelectedVideo');
|
||||
}, 300);
|
||||
}
|
||||
!ui.item && pandora.UI.set('listSelection', [item]);
|
||||
} else {
|
||||
$('.OxSelectedVideo').removeClass('OxSelectedVideo');
|
||||
!ui.item && pandora.UI.set('listSelection', []);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return that;
|
||||
|
||||
}
|
|
@ -1,84 +1,107 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=javascript
|
||||
pandora.ui.info = function() {
|
||||
var id = pandora.user.ui.item || (
|
||||
pandora.user.ui.listSelection.length
|
||||
? pandora.user.ui.listSelection[pandora.user.ui.listSelection.length - 1]
|
||||
: null
|
||||
),
|
||||
|
||||
var ui = pandora.user.ui,
|
||||
view = getView(),
|
||||
|
||||
that = Ox.Element()
|
||||
.css({overflowX: 'hidden', overflowY: 'auto'})
|
||||
.bindEvent({
|
||||
toggle: function(data) {
|
||||
pandora.UI.set({showInfo: !data.collapsed});
|
||||
pandora.resizeFolders();
|
||||
}
|
||||
},
|
||||
pandora_find: function() {
|
||||
if (pandora.user.ui._list != pandora.UI.getPrevious('_list')) {
|
||||
updateInfo();
|
||||
}
|
||||
},
|
||||
pandora_item: updateInfo,
|
||||
pandora_listselection: updateInfo
|
||||
});
|
||||
Ox.print('INFO', view)
|
||||
if (view == 'list') {
|
||||
that.empty().append(pandora.$ui.listInfo = pandora.ui.listInfo(pandora.user.ui._list));
|
||||
} else if (view == 'poster') {
|
||||
pandora.api.get({id: id, keys: ['director', 'posterRatio', 'title']}, function(result) {
|
||||
var ratio = result.data.posterRatio,
|
||||
height = pandora.getInfoHeight();
|
||||
that.empty().append(
|
||||
pandora.$ui.posterInfo = pandora.ui.posterInfo(Ox.extend(result.data, {id: id}))
|
||||
);
|
||||
});
|
||||
} else if (view == 'video') {
|
||||
pandora.api.get({id: id, keys: ['duration', 'videoRatio']}, function(result) {
|
||||
if (result.data) {
|
||||
pandora.$ui.videoPreview && pandora.$ui.videoPreview.removeElement();
|
||||
pandora.$ui.videoPreview = pandora.ui.videoPreview({
|
||||
duration: result.data.duration,
|
||||
frameRatio: result.data.videoRatio,
|
||||
height: pandora.getInfoHeight(),
|
||||
id: id,
|
||||
width: pandora.user.ui.sidebarSize
|
||||
})
|
||||
.bindEvent({
|
||||
click: function(data) {
|
||||
pandora.UI.set(
|
||||
'videoPoints.' + id,
|
||||
{'in': 0, out: 0, position: data.position}
|
||||
);
|
||||
if (pandora.user.ui.item && ['video', 'timeline'].indexOf(pandora.user.ui.itemView) > -1) {
|
||||
pandora.$ui[
|
||||
pandora.user.ui.itemView == 'video' ? 'player' : 'editor'
|
||||
].options({
|
||||
position: data.position
|
||||
});
|
||||
} else {
|
||||
pandora.UI.set({
|
||||
item: id,
|
||||
itemView: pandora.user.ui.videoView
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.appendTo(pandora.$ui.info);
|
||||
}
|
||||
});
|
||||
|
||||
//pandora.$ui.leftPanel && resize();
|
||||
|
||||
updateInfo();
|
||||
|
||||
function getId() {
|
||||
return ui.item || (
|
||||
ui.listSelection.length
|
||||
? ui.listSelection[ui.listSelection.length - 1]
|
||||
: null
|
||||
);
|
||||
}
|
||||
pandora.$ui.leftPanel && resize();
|
||||
|
||||
function getView() {
|
||||
return !id ? 'list'
|
||||
: !pandora.user.ui.item && pandora.isClipView() ? 'poster'
|
||||
return !getId() ? 'list'
|
||||
: !ui.item && pandora.isClipView() ? 'poster'
|
||||
: 'video';
|
||||
}
|
||||
function resize() {
|
||||
|
||||
function resizeInfo() {
|
||||
var height = pandora.getInfoHeight();
|
||||
if (height != pandora.$ui.leftPanel.size(2)) {
|
||||
!pandora.user.ui.showInfo && pandora.$ui.leftPanel.css({bottom: -height});
|
||||
// fixme: why is this timeout needed?
|
||||
setTimeout(function() {
|
||||
pandora.$ui.leftPanel.size(2, height, function() {
|
||||
pandora.resizeFolders();
|
||||
});
|
||||
}, 0)
|
||||
!pandora.user.ui.showInfo && pandora.$ui.leftPanel.css({bottom: -height});
|
||||
pandora.$ui.leftPanel.size(2, height, function() {
|
||||
pandora.resizeFolders();
|
||||
});
|
||||
}
|
||||
|
||||
function updateInfo() {
|
||||
var id = getId(),
|
||||
previousView = view;
|
||||
view = getView();
|
||||
if (view == 'list') {
|
||||
that.empty().append(pandora.$ui.listInfo = pandora.ui.listInfo(ui._list));
|
||||
previousView == 'video' && resizeInfo();
|
||||
} else if (view == 'poster') {
|
||||
pandora.api.get({id: id, keys: ['director', 'posterRatio', 'title']}, function(result) {
|
||||
var ratio = result.data.posterRatio,
|
||||
height = pandora.getInfoHeight();
|
||||
that.empty().append(
|
||||
pandora.$ui.posterInfo = pandora.ui.posterInfo(Ox.extend(result.data, {id: id}))
|
||||
);
|
||||
previousView == 'video' && resizeInfo();
|
||||
});
|
||||
} else if (view == 'video') {
|
||||
pandora.api.get({id: id, keys: ['duration', 'videoRatio']}, function(result) {
|
||||
if (result.data) {
|
||||
pandora.$ui.videoPreview && pandora.$ui.videoPreview.removeElement();
|
||||
pandora.$ui.videoPreview = pandora.ui.videoPreview({
|
||||
duration: result.data.duration,
|
||||
frameRatio: result.data.videoRatio,
|
||||
height: pandora.getInfoHeight(),
|
||||
id: id,
|
||||
width: ui.sidebarSize
|
||||
})
|
||||
.bindEvent({
|
||||
click: function(data) {
|
||||
pandora.UI.set(
|
||||
'videoPoints.' + id,
|
||||
{'in': 0, out: 0, position: data.position}
|
||||
);
|
||||
if (ui.item && ['video', 'timeline'].indexOf(ui.itemView) > -1) {
|
||||
pandora.$ui[
|
||||
ui.itemView == 'video' ? 'player' : 'editor'
|
||||
].options({
|
||||
position: data.position
|
||||
});
|
||||
} else {
|
||||
pandora.UI.set({
|
||||
item: id,
|
||||
itemView: ui.videoView
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.appendTo(pandora.$ui.info);
|
||||
previousView != 'video' && resizeInfo();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
that.resizeInfo = function() {
|
||||
var view = getView();
|
||||
if (view == 'list') {
|
||||
pandora.$ui.listInfo.resizeIcon();
|
||||
} else if (view == 'poster') {
|
||||
|
@ -86,11 +109,13 @@ pandora.ui.info = function() {
|
|||
} else if (view == 'video') {
|
||||
pandora.$ui.videoPreview.options({
|
||||
height: pandora.getInfoHeight(),
|
||||
width: pandora.user.ui.sidebarSize
|
||||
width: ui.sidebarSize
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return that;
|
||||
|
||||
};
|
||||
|
||||
pandora.ui.listInfo = function(data) {
|
||||
|
@ -137,7 +162,7 @@ pandora.ui.posterInfo = function(data) {
|
|||
data.title + (
|
||||
data.director ? ' (' + data.director.join(', ') + ')' : ''
|
||||
)
|
||||
);
|
||||
),
|
||||
that = Ox.SplitPanel({
|
||||
elements: [
|
||||
{
|
||||
|
|
|
@ -197,114 +197,14 @@ pandora.ui.item = function() {
|
|||
}
|
||||
|
||||
} else if (pandora.user.ui.itemView == 'clips') {
|
||||
var ratio = result.data.videoRatio;
|
||||
pandora.$ui.contentPanel.replaceElement(1, pandora.$ui.clips = Ox.IconList({
|
||||
fixedRatio: ratio,
|
||||
item: function(data, sort, size) {
|
||||
size = size || 128;
|
||||
var width = ratio > 1 ? size : Math.round(size * ratio),
|
||||
height = ratio > 1 ? Math.round(size / ratio) : size,
|
||||
url = '/' + pandora.user.ui.item + '/' + height + 'p' + data['in'] + '.jpg';
|
||||
return {
|
||||
height: height,
|
||||
id: data['id'],
|
||||
info: Ox.formatDuration(data['in'], 'short') + ' - ' + Ox.formatDuration(data['out'], 'short'),
|
||||
title: data.value,
|
||||
url: url,
|
||||
width: width
|
||||
};
|
||||
},
|
||||
items: function(data, callback) {
|
||||
pandora.api.findAnnotations(Ox.extend(data, {
|
||||
itemQuery: {
|
||||
conditions:[{
|
||||
key: 'id',
|
||||
value: pandora.user.ui.item,
|
||||
operator: '='
|
||||
}],
|
||||
pandora.$ui.contentPanel.replaceElement(1,
|
||||
pandora.$ui.clips = pandora.ui.clipList(result.data.videoRatio)
|
||||
.bindEvent({
|
||||
pandora_itemsort: function(data) {
|
||||
pandora.$ui.clips.options({sort: data.value});
|
||||
}
|
||||
}), callback);
|
||||
},
|
||||
keys: ['id', 'value', 'in', 'out'],
|
||||
size: 128,
|
||||
sort: pandora.user.ui.itemSort,
|
||||
unique: 'id'
|
||||
}).bindEvent({
|
||||
open: function(data) {
|
||||
var id = data.ids[0],
|
||||
points = {
|
||||
'in': pandora.$ui.clips.value(id, 'in'),
|
||||
out: pandora.$ui.clips.value(id, 'out')
|
||||
};
|
||||
pandora.UI.set('videoPoints.' + pandora.user.ui.item, Ox.extend(points, {
|
||||
position: points['in']
|
||||
}));
|
||||
pandora.UI.set({
|
||||
itemView: pandora.user.ui.videoView
|
||||
});
|
||||
},
|
||||
// fixme: duplicated
|
||||
openpreview: function(data) {
|
||||
var $video = $('.OxItem.OxSelected > .OxIcon > .OxVideoPlayer');
|
||||
if ($video) {
|
||||
// trigger singleclick
|
||||
$video.trigger('mousedown');
|
||||
Ox.UI.$window.trigger('mouseup');
|
||||
}
|
||||
that.closePreview();
|
||||
},
|
||||
select: function(data) {
|
||||
if (data.ids.length) {
|
||||
var id = data.ids[0],
|
||||
item = id.split('/')[0], width, height,
|
||||
$img = pandora.$ui.clips.find('.OxItem.OxSelected > .OxIcon > img'),
|
||||
$video = $('.OxItem.OxSelected > .OxIcon > .OxVideoPlayer');
|
||||
if ($img.length) {
|
||||
var width = ratio > 1 ? 128 : Math.round(128 * ratio),
|
||||
height = ratio > 1 ? Math.round(128 / ratio) : 128;
|
||||
pandora.api.get({id: item, keys: ['durations']}, function(result) {
|
||||
var points = [pandora.$ui.clips.value(id, 'in'), pandora.$ui.clips.value(id, 'out')],
|
||||
partsAndPoints = pandora.getVideoPartsAndPoints(result.data.durations, points),
|
||||
$player = Ox.VideoPlayer({
|
||||
height: height,
|
||||
'in': partsAndPoints.points[0],
|
||||
out: partsAndPoints.points[1],
|
||||
paused: true,
|
||||
playInToOut: true,
|
||||
poster: '/' + item + '/' + height + 'p' + points[0] + '.jpg',
|
||||
width: width,
|
||||
video: partsAndPoints.parts.map(function(i) {
|
||||
return '/' + item + '/96p' + (i + 1) + '.' + pandora.user.videoFormat;
|
||||
})
|
||||
})
|
||||
.addClass('OxTarget')
|
||||
.bindEvent({
|
||||
// doubleclick opens item
|
||||
singleclick: function() {
|
||||
$player.$element.is('.OxSelectedVideo') && $player.togglePaused();
|
||||
}
|
||||
});
|
||||
$img.replaceWith($player.$element);
|
||||
$('.OxSelectedVideo').removeClass('OxSelectedVideo');
|
||||
$player.$element.addClass('OxSelectedVideo');
|
||||
});
|
||||
} else if ($video.length) {
|
||||
// item select fires before video click
|
||||
// so we have to make sure that selecting
|
||||
// doesn't click through to play
|
||||
setTimeout(function() {
|
||||
$('.OxSelectedVideo').removeClass('OxSelectedVideo');
|
||||
$video.addClass('OxSelectedVideo');
|
||||
}, 300);
|
||||
}
|
||||
} else {
|
||||
$('.OxSelectedVideo').removeClass('OxSelectedVideo');
|
||||
}
|
||||
},
|
||||
pandora_itemsort: function(data) {
|
||||
pandora.$ui.clips.options({sort: data.value});
|
||||
}
|
||||
}));
|
||||
})
|
||||
);
|
||||
|
||||
} else if (pandora.user.ui.itemView == 'video') {
|
||||
// fixme: duplicated
|
||||
|
@ -477,103 +377,7 @@ pandora.ui.item = function() {
|
|||
|
||||
|
||||
} else if (pandora.user.ui.itemView == 'map') {
|
||||
var video = result.data.stream;
|
||||
pandora.$ui.contentPanel.replaceElement(1, Ox.SplitPanel({
|
||||
elements: [
|
||||
{
|
||||
element: pandora.$ui.map = Ox.Map({
|
||||
height: window.innerHeight - pandora.user.ui.showGroups * pandora.user.ui.groupsSize - 61,
|
||||
places: function(data, callback) {
|
||||
var itemQuery = {conditions: [{
|
||||
key: 'id',
|
||||
value: pandora.user.ui.item,
|
||||
operator: '='
|
||||
}]},
|
||||
query = {conditions:[]};
|
||||
return pandora.api.findPlaces(Ox.extend(data, {
|
||||
itemQuery: itemQuery,
|
||||
query: query
|
||||
}), callback);
|
||||
},
|
||||
showTypes: true,
|
||||
toolbar: true,
|
||||
width: window.innerWidth - pandora.user.ui.showSidebar * pandora.user.ui.sidebarSize - 2 - 144 - Ox.UI.SCROLLBAR_SIZE
|
||||
}).bindEvent({
|
||||
selectplace: function(place) {
|
||||
if(place) {
|
||||
pandora.$ui.clips.options({
|
||||
items: function(data, callback) {
|
||||
return pandora.api.findAnnotations(Ox.extend(data, {
|
||||
query: {
|
||||
conditions:[{
|
||||
key: 'place',
|
||||
value: place.id,
|
||||
operator:'=='
|
||||
}]
|
||||
},
|
||||
itemQuery: {conditions: [{
|
||||
key: 'id',
|
||||
value: pandora.user.ui.item,
|
||||
operator: '=='
|
||||
}]}
|
||||
}), callback);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
pandora.$ui.clips.options({
|
||||
items: []
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
element: pandora.$ui.clips = Ox.IconList({
|
||||
fixedRatio: video.aspectRatio,
|
||||
item: function(data, sort, size) {
|
||||
size = size || 128;
|
||||
Ox.print('DATA', data);
|
||||
var width = size,
|
||||
height = Math.round(size / video.aspectRatio),
|
||||
itemId = data.id.split('/')[0],
|
||||
url = '/' + itemId + '/' + height + 'p' + data['in'] + '.jpg';
|
||||
return {
|
||||
height: height,
|
||||
id: data['id'],
|
||||
info: Ox.formatDuration(data['in'], 'short') +' - '+ Ox.formatDuration(data['out'], 'short'),
|
||||
title: data.value,
|
||||
url: url,
|
||||
width: width
|
||||
};
|
||||
},
|
||||
items: [],
|
||||
keys: ['id', 'value', 'in', 'out'],
|
||||
size: 128,
|
||||
sort: pandora.user.ui.itemSort,
|
||||
unique: 'id'
|
||||
}).bindEvent({
|
||||
open: function(data) {
|
||||
var id = data.ids[0],
|
||||
item = pandora.user.ui.item,
|
||||
points = {
|
||||
'in': pandora.$ui.clips.value(id, 'in'),
|
||||
out: pandora.$ui.clips.value(id, 'out')
|
||||
};
|
||||
pandora.UI.set('videoPoints.' + item, Ox.extend(points, {
|
||||
position: points['in']
|
||||
}));
|
||||
pandora.UI.set('itemView', 'timeline');
|
||||
}
|
||||
}),
|
||||
id: 'place',
|
||||
size: 144 + Ox.UI.SCROLLBAR_SIZE
|
||||
}
|
||||
],
|
||||
orientation: 'horizontal'
|
||||
})
|
||||
.bindEvent('resize', function() {
|
||||
pandora.$ui.map.resizeMap();
|
||||
}));
|
||||
pandora.$ui.contentPanel.replaceElement(1, pandora.ui.mapView(result.data.videoRatio));
|
||||
|
||||
} else if (pandora.user.ui.itemView == 'calendar') {
|
||||
pandora.$ui.contentPanel.replaceElement(1, Ox.Element().html('Calendar'));
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=javascript
|
||||
|
||||
pandora.ui.list = function() {
|
||||
var that, $map,
|
||||
var that
|
||||
view = pandora.user.ui.listView,
|
||||
preview = false
|
||||
|
||||
|
@ -225,132 +225,7 @@ pandora.ui.list = function() {
|
|||
} else if (view == 'calendars') {
|
||||
that = Ox.Element().css({margin: '16px'}).html(view + ' results view still missing.');
|
||||
} else if (view == 'clip') {
|
||||
var fixedRatio = 16/9;
|
||||
that = Ox.IconList({
|
||||
fixedRatio: fixedRatio,
|
||||
item: function(data, sort, size) {
|
||||
size = size || 128;
|
||||
var ratio = data.videoRatio,
|
||||
width = ratio > fixedRatio ? size : Math.round(size * ratio / fixedRatio),
|
||||
height = Math.round(width / ratio),
|
||||
url = '/' + data.id.split('/')[0] + '/' + height + 'p' + data['in'] + '.jpg',
|
||||
sortKey = sort[0].key.split(':').pop(),
|
||||
info = ['hue', 'saturation', 'lightness'].indexOf(sortKey) > -1
|
||||
? Ox.formatColor(data[sortKey], sortKey)
|
||||
: data[['title', 'director'].indexOf(sort[0].key) > -1 ? 'year' : sort[0].key];
|
||||
return {
|
||||
height: height,
|
||||
id: data.id,
|
||||
info: sort[0].key == 'clip:hue' ? Ox.formatColor(data['hue'], 'hue')
|
||||
: sort[0].key == 'clip:saturation' ? Ox.formatColor(data['saturation'], 'saturation')
|
||||
: sort[0].key == 'clip:lightness' ? Ox.formatColor(data['lightness'], 'lightness')
|
||||
: Ox.formatDuration(data['in'], 'short') + ' - ' + Ox.formatDuration(data['out'], 'short'),
|
||||
title: data.value,
|
||||
url: url,
|
||||
width: width
|
||||
};
|
||||
},
|
||||
items: function(data, callback) {
|
||||
var itemQuery = pandora.user.ui.find,
|
||||
query = {conditions:[]};
|
||||
//fixme: can this be in pandora.Query? dont just check for subtitles
|
||||
itemQuery.conditions.forEach(function(q) {
|
||||
if (q.key == 'subtitles') {
|
||||
query.conditions.push({key: 'value', value: q.value, operator: q.operator});
|
||||
}
|
||||
});
|
||||
pandora.api.findAnnotations(Ox.extend({
|
||||
query: query,
|
||||
itemQuery: itemQuery
|
||||
}, data), callback);
|
||||
},
|
||||
keys: ['id', 'value', 'in', 'out', 'videoRatio'],
|
||||
max: 1,
|
||||
size: 128,
|
||||
sort: pandora.user.ui.listSort,
|
||||
unique: 'id'
|
||||
}).bindEvent({
|
||||
init: function(data) {
|
||||
pandora.$ui.total.html(pandora.ui.status('total', data));
|
||||
},
|
||||
open: function(data) {
|
||||
var id = data.ids[0],
|
||||
item = id.split('/')[0],
|
||||
points = {
|
||||
'in': that.value(id, 'in'),
|
||||
out: that.value(id, 'out')
|
||||
};
|
||||
pandora.UI.set('videoPoints.' + item, Ox.extend(points, {
|
||||
position: points['in']
|
||||
}));
|
||||
pandora.UI.set({
|
||||
item: item,
|
||||
itemView: pandora.user.ui.videoView
|
||||
});
|
||||
pandora.URL.push();
|
||||
},
|
||||
openpreview: function(data) {
|
||||
var $video = $('.OxItem.OxSelected > .OxIcon > .OxVideoPlayer');
|
||||
if ($video) {
|
||||
// trigger singleclick
|
||||
$video.trigger('mousedown');
|
||||
Ox.UI.$window.trigger('mouseup');
|
||||
}
|
||||
that.closePreview();
|
||||
},
|
||||
select: function(data) {
|
||||
if (data.ids.length) {
|
||||
var id = data.ids[0],
|
||||
item = id.split('/')[0], width, height,
|
||||
$img = $('.OxItem.OxSelected > .OxIcon > img'),
|
||||
$video = $('.OxItem.OxSelected > .OxIcon > .OxVideoPlayer');
|
||||
pandora.UI.set('listSelection', [item]);
|
||||
pandora.$ui.leftPanel.replaceElement(2, pandora.$ui.info = pandora.ui.info());
|
||||
if ($img.length) {
|
||||
var width = parseInt($img.css('width')),
|
||||
height = parseInt($img.css('height'));
|
||||
pandora.api.get({id: item, keys: ['durations']}, function(result) {
|
||||
var points = [that.value(id, 'in'), that.value(id, 'out')],
|
||||
partsAndPoints = pandora.getVideoPartsAndPoints(result.data.durations, points),
|
||||
$player = Ox.VideoPlayer({
|
||||
height: height,
|
||||
'in': partsAndPoints.points[0],
|
||||
out: partsAndPoints.points[1],
|
||||
paused: true,
|
||||
playInToOut: true,
|
||||
poster: '/' + item + '/' + height + 'p' + points[0] + '.jpg',
|
||||
width: width,
|
||||
video: partsAndPoints.parts.map(function(i) {
|
||||
return '/' + item + '/96p' + (i + 1) + '.' + pandora.user.videoFormat;
|
||||
})
|
||||
})
|
||||
.addClass('OxTarget')
|
||||
.bindEvent({
|
||||
// doubleclick opens item
|
||||
singleclick: function() {
|
||||
$player.$element.is('.OxSelectedVideo') && $player.togglePaused();
|
||||
}
|
||||
});
|
||||
$img.replaceWith($player.$element);
|
||||
$('.OxSelectedVideo').removeClass('OxSelectedVideo');
|
||||
$player.$element.addClass('OxSelectedVideo');
|
||||
});
|
||||
} else if ($video.length) {
|
||||
// item select fires before video click
|
||||
// so we have to make sure that selecting
|
||||
// doesn't click through to play
|
||||
setTimeout(function() {
|
||||
$('.OxSelectedVideo').removeClass('OxSelectedVideo');
|
||||
$video.addClass('OxSelectedVideo');
|
||||
}, 300);
|
||||
}
|
||||
} else {
|
||||
pandora.UI.set('listSelection', []);
|
||||
pandora.$ui.leftPanel.replaceElement(2, pandora.$ui.info = pandora.ui.info());
|
||||
$('.OxSelectedVideo').removeClass('OxSelectedVideo');
|
||||
}
|
||||
}
|
||||
});
|
||||
that = pandora.ui.clipList();
|
||||
} else if (view == 'player') {
|
||||
that = Ox.VideoPlayer({
|
||||
controlsBottom: ['play', 'previous', 'next', 'volume'],
|
||||
|
@ -408,94 +283,7 @@ pandora.ui.list = function() {
|
|||
width: 512
|
||||
});
|
||||
} else if (view == 'map') {
|
||||
var fixedRatio = 16/9;
|
||||
that = Ox.SplitPanel({
|
||||
elements: [
|
||||
{
|
||||
element: pandora.$ui.map = Ox.Map({
|
||||
height: window.innerHeight - pandora.user.ui.showGroups * pandora.user.ui.groupsSize - 61,
|
||||
places: function(data, callback) {
|
||||
var itemQuery = pandora.user.ui.find,
|
||||
query = {conditions:[]};
|
||||
return pandora.api.findPlaces(Ox.extend(data, {
|
||||
itemQuery: itemQuery,
|
||||
query: query
|
||||
}), callback);
|
||||
},
|
||||
showTypes: true,
|
||||
toolbar: true,
|
||||
width: window.innerWidth - pandora.user.ui.showSidebar * pandora.user.ui.sidebarSize - 2 - 144 - Ox.UI.SCROLLBAR_SIZE,
|
||||
}).bindEvent({
|
||||
selectplace: function(place) {
|
||||
if(place && place.id[0] != '_') {
|
||||
pandora.$ui.clips.options({
|
||||
items: function(data, callback) {
|
||||
return pandora.api.findAnnotations(Ox.extend(data, {
|
||||
query: {
|
||||
conditions:[{key: 'place',
|
||||
value: place.id,
|
||||
operator:'=='
|
||||
}]
|
||||
},
|
||||
itemQuery: pandora.user.ui.find
|
||||
}), callback);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
pandora.$ui.clips.options({
|
||||
items: []
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
element: pandora.$ui.clips = Ox.IconList({
|
||||
fixedRatio: fixedRatio,
|
||||
item: function(data, sort, size) {
|
||||
size = size || 128;
|
||||
var width = data.videoRatio < fixedRatio ? size : size * data.videoRatio / fixedRatio,
|
||||
height = Math.round(width / data.videoRatio),
|
||||
itemId = data.id.split('/')[0],
|
||||
url = '/' + itemId + '/' + height + 'p' + data['in'] + '.jpg';
|
||||
return {
|
||||
height: height,
|
||||
id: data.id,
|
||||
info: Ox.formatDuration(data['in'], 'short') + ' - '
|
||||
+ Ox.formatDuration(data['out'], 'short'),
|
||||
title: data.value,
|
||||
url: url,
|
||||
width: width
|
||||
};
|
||||
},
|
||||
items: [],
|
||||
keys: ['id', 'value', 'in', 'out', 'videoRatio'],
|
||||
size: 128,
|
||||
sort: pandora.user.ui.listSort,
|
||||
unique: 'id'
|
||||
}).bindEvent({
|
||||
open: function(data) {
|
||||
var id = data.ids[0],
|
||||
item = pandora.$ui.clips.value(id, 'item'),
|
||||
points = {
|
||||
'in': pandora.$ui.clips.value(id, 'in'),
|
||||
out: pandora.$ui.clips.value(id, 'out')
|
||||
};
|
||||
pandora.UI.set('videoPoints.' + item, Ox.extend(points, {
|
||||
position: points['in']
|
||||
}));
|
||||
pandora.UI.set('itemView', 'timeline');
|
||||
}
|
||||
}),
|
||||
id: 'clips',
|
||||
size: 144 + Ox.UI.SCROLLBAR_SIZE
|
||||
}
|
||||
],
|
||||
orientation: 'horizontal'
|
||||
})
|
||||
.bindEvent('resize', function() {
|
||||
pandora.$ui.map.resizeMap();
|
||||
});
|
||||
that = pandora.ui.mapView();
|
||||
} else if (view == 'calendar') {
|
||||
var fixedRatio = 16/9;
|
||||
that = Ox.SplitPanel({
|
||||
|
|
207
static/js/pandora/ui/mapView.js
Normal file
207
static/js/pandora/ui/mapView.js
Normal file
|
@ -0,0 +1,207 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=javascript
|
||||
|
||||
pandora.ui.mapView = function(videoRatio) {
|
||||
|
||||
var ui = pandora.user.ui,
|
||||
|
||||
listSizes = [
|
||||
144 + Ox.UI.SCROLLBAR_SIZE,
|
||||
280 + Ox.UI.SCROLLBAR_SIZE,
|
||||
416 + Ox.UI.SCROLLBAR_SIZE
|
||||
],
|
||||
listSize = listSizes[ui.clipsColumns - 1],
|
||||
|
||||
$map = Ox.Map({
|
||||
// 20 menu + 24 toolbar + 1 resizebar + 16 statusbar
|
||||
height: window.innerHeight - ui.showGroups * ui.groupsSize - 61,
|
||||
places: function(data, callback) {
|
||||
var itemQuery;
|
||||
if (!ui.item) {
|
||||
itemQuery = ui.find;
|
||||
} else {
|
||||
itemQuery = {
|
||||
conditions: [{key: 'id', value: ui.item, operator: '=='}],
|
||||
operator: '&'
|
||||
};
|
||||
}
|
||||
return pandora.api.findPlaces(Ox.extend(data, {
|
||||
itemQuery: itemQuery,
|
||||
query: {conditions: [], operator: '&'}
|
||||
}), callback);
|
||||
},
|
||||
showTypes: true,
|
||||
toolbar: true,
|
||||
width: window.innerWidth - ui.showSidebar * ui.sidebarSize - listSize - 2,
|
||||
zoombar: true
|
||||
})
|
||||
.bindEvent({
|
||||
resize: function() {
|
||||
$map.resizeMap();
|
||||
},
|
||||
selectplace: function(data) {
|
||||
var id = data.id || '';
|
||||
if (id && id[0] != '_') {
|
||||
$list.options({
|
||||
items: function(data, callback) {
|
||||
var itemQuery;
|
||||
if (!ui.item) {
|
||||
itemQuery = ui.find;
|
||||
} else {
|
||||
itemQuery = {
|
||||
conditions: [{key: 'id', value: ui.item, operator: '=='}],
|
||||
operator: '&'
|
||||
};
|
||||
}
|
||||
return pandora.api.findAnnotations(Ox.extend({
|
||||
itemQuery: itemQuery,
|
||||
query: {
|
||||
conditions: [{key: 'place', value: id, operator:'=='}],
|
||||
operator: '&'
|
||||
},
|
||||
}, data), callback);
|
||||
}
|
||||
});
|
||||
updateToolbar(data);
|
||||
} else {
|
||||
$list.options({items: []});
|
||||
updateToolbar();
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
$placeFlag = $('<img>')
|
||||
.addClass('OxFlag')
|
||||
.attr({
|
||||
src: Ox.getImageByGeoname('icon', 16, '')
|
||||
})
|
||||
.css({float: 'left', margin: '4px'}),
|
||||
|
||||
$placeName = Ox.Label({
|
||||
textAlign: 'center',
|
||||
title: '',
|
||||
width: 96 + Ox.UI.SCROLLBAR_SIZE
|
||||
})
|
||||
.css({float: 'left', margin: '4px 0 4px 0'}),
|
||||
|
||||
$placeButton = Ox.Button({
|
||||
title: 'close',
|
||||
type: 'image'
|
||||
})
|
||||
.css({float: 'left', margin: '4px'})
|
||||
.bindEvent({
|
||||
click: function() {
|
||||
$map.options({selected: null});
|
||||
}
|
||||
}),
|
||||
|
||||
$place = $('<div>')
|
||||
.append($placeFlag)
|
||||
.append($placeName)
|
||||
.append($placeButton),
|
||||
|
||||
$toolbar = Ox.Bar({size: 24})
|
||||
.append($place),
|
||||
|
||||
$list = pandora.ui.clipList(videoRatio)
|
||||
.bindEvent({
|
||||
init: function(data) {
|
||||
updateStatusbar(data.items);
|
||||
}
|
||||
}),
|
||||
|
||||
$status = $('<div>')
|
||||
.css({
|
||||
width: '100%',
|
||||
marginTop: '2px',
|
||||
fontSize: '9px',
|
||||
textAlign: 'center',
|
||||
textOverflow: 'ellipsis'
|
||||
}),
|
||||
|
||||
$statusbar = Ox.Bar({size: 16}).append($status),
|
||||
|
||||
$listPanel = Ox.SplitPanel({
|
||||
elements: [
|
||||
{
|
||||
element: $toolbar,
|
||||
size: 24
|
||||
},
|
||||
{
|
||||
element: $list
|
||||
},
|
||||
{
|
||||
element: $statusbar,
|
||||
size: 16
|
||||
}
|
||||
],
|
||||
orientation: 'vertical'
|
||||
})
|
||||
.bindEvent({
|
||||
resize: function(data) {
|
||||
resizeToolbar(data.size);
|
||||
$list.size();
|
||||
},
|
||||
resizeend: function(data) {
|
||||
var size = data.size;
|
||||
if (listSizes.indexOf(size) == -1) {
|
||||
if (size <= (listSizes[0] + listSizes[1]) / 2) {
|
||||
size = listSizes[0];
|
||||
} else if (size < (listSizes[1] + listSizes[2]) / 2) {
|
||||
size = listSizes[1];
|
||||
} else {
|
||||
size = listSizes[2];
|
||||
}
|
||||
that.size(1, size, function() {
|
||||
$map.resizeMap();
|
||||
resizeToolbar(size);
|
||||
// strangely, the animation may still not be fully
|
||||
// finished, causing the list size to be off by one
|
||||
setTimeout($list.size, 0);
|
||||
});
|
||||
}
|
||||
pandora.UI.set({clipsColumns: listSizes.indexOf(size) + 1});
|
||||
}
|
||||
}),
|
||||
|
||||
that = Ox.SplitPanel({
|
||||
elements: [
|
||||
{
|
||||
element: $map,
|
||||
},
|
||||
{
|
||||
element: $listPanel,
|
||||
resizable: true,
|
||||
resize: listSizes,
|
||||
size: listSize,
|
||||
tooltip: 'clips'
|
||||
}
|
||||
],
|
||||
orientation: 'horizontal'
|
||||
});
|
||||
|
||||
resizeToolbar(listSize);
|
||||
updateToolbar();
|
||||
updateStatusbar();
|
||||
|
||||
function resizeToolbar(width) {
|
||||
$placeName.options({width: width - 48});
|
||||
}
|
||||
|
||||
function updateStatusbar(items) {
|
||||
$status.html((items || 'No') + ' clip' + (items == 1 ? '' : 's'));
|
||||
}
|
||||
|
||||
function updateToolbar(place) {
|
||||
$placeFlag.attr({
|
||||
src: Ox.getImageByGeoname('icon', 16, place ? place.geoname : '')
|
||||
});
|
||||
$placeName.options({title: place ? place.name : 'No place'});
|
||||
$placeButton.options({disabled: !place});
|
||||
}
|
||||
|
||||
// fixme: this is needed for the main window resize handler
|
||||
pandora.$ui.map = $map;
|
||||
|
||||
return that;
|
||||
|
||||
};
|
|
@ -44,6 +44,9 @@ pandora.ui.siteDialog = function(section) {
|
|||
$dialog.options({
|
||||
title: Ox.getObjectById(tabs, data.selected).title
|
||||
});
|
||||
//fixme: this should be using URL.push / UI.set
|
||||
//but that currenlty causes another dialog to be opened
|
||||
history.pushState({}, '', '/' + data.selected);
|
||||
}
|
||||
});
|
||||
var $dialog = Ox.Dialog({
|
||||
|
@ -54,7 +57,9 @@ pandora.ui.siteDialog = function(section) {
|
|||
}).bindEvent({
|
||||
click: function() {
|
||||
$dialog.close();
|
||||
pandora.URL.push();
|
||||
//fixme: this should be using URL.push / UI.set
|
||||
//but that currenlty causes a reload
|
||||
history.pushState({}, '', '/');
|
||||
}
|
||||
})
|
||||
],
|
||||
|
|
|
@ -435,12 +435,9 @@ pandora.getGroupsSizes = function() {
|
|||
|
||||
pandora.getInfoHeight = function() {
|
||||
// fixme: new, check if it can be used more
|
||||
var isVideoPreview
|
||||
if (!pandora.user.ui.item) {
|
||||
isVideoPreview = pandora.user.ui.listSelection.length && !pandora.isClipView();
|
||||
} else {
|
||||
isVideoPreview = !pandora.isClipView();
|
||||
}
|
||||
var isVideoPreview = pandora.user.ui.item || (
|
||||
pandora.user.ui.listSelection.length && !pandora.isClipView()
|
||||
);
|
||||
return pandora.user.ui.showInfo * Math.min(
|
||||
isVideoPreview
|
||||
? Math.round(pandora.user.ui.sidebarSize / (16/9)) + 16
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
"js/pandora/ui/appPanel.js",
|
||||
"js/pandora/ui/backButton.js",
|
||||
"js/pandora/ui/browser.js",
|
||||
"js/pandora/ui/clipList.js",
|
||||
"js/pandora/ui/contentPanel.js",
|
||||
"js/pandora/ui/deleteListDialog.js",
|
||||
"js/pandora/ui/editor.js",
|
||||
|
@ -31,6 +32,7 @@
|
|||
"js/pandora/ui/list.js",
|
||||
"js/pandora/ui/listDialog.js",
|
||||
"js/pandora/ui/mainPanel.js",
|
||||
"js/pandora/ui/mapView.js",
|
||||
"js/pandora/ui/mediaView.js",
|
||||
"js/pandora/ui/menu.js",
|
||||
"js/pandora/ui/orderButton.js",
|
||||
|
|
Loading…
Reference in a new issue