url controller update
This commit is contained in:
parent
3c03d4fd68
commit
deb208dcba
13 changed files with 248 additions and 146 deletions
|
@ -432,6 +432,7 @@
|
||||||
"value": "capability"
|
"value": "capability"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"fixme": "itemNames should be lowercase!",
|
||||||
"itemName": {
|
"itemName": {
|
||||||
"singular": "Movie",
|
"singular": "Movie",
|
||||||
"plural": "Movies"
|
"plural": "Movies"
|
||||||
|
@ -473,7 +474,7 @@
|
||||||
],
|
],
|
||||||
"listViews": [
|
"listViews": [
|
||||||
{"id": "list", "title": "as List"},
|
{"id": "list", "title": "as List"},
|
||||||
{"id": "icons", "title": "as Icons"},
|
{"id": "grid", "title": "as Grid"},
|
||||||
{"id": "info", "title": "with Info"},
|
{"id": "info", "title": "with Info"},
|
||||||
{"id": "clips", "title": "with Clips"},
|
{"id": "clips", "title": "with Clips"},
|
||||||
{"id": "timelines", "title": "with Timelines"},
|
{"id": "timelines", "title": "with Timelines"},
|
||||||
|
@ -555,7 +556,7 @@
|
||||||
"": {
|
"": {
|
||||||
"columns": ["title", "director", "country", "year", "language", "runtime", "genre"],
|
"columns": ["title", "director", "country", "year", "language", "runtime", "genre"],
|
||||||
"columnWidth": {},
|
"columnWidth": {},
|
||||||
"listView": "icons",
|
"listView": "grid",
|
||||||
"selected": [],
|
"selected": [],
|
||||||
"sort": [
|
"sort": [
|
||||||
{"key": "director", "operator": ""}
|
{"key": "director", "operator": ""}
|
||||||
|
@ -583,7 +584,7 @@
|
||||||
"sidebarSize": 256,
|
"sidebarSize": 256,
|
||||||
"sitePage": "home",
|
"sitePage": "home",
|
||||||
"theme": "modern",
|
"theme": "modern",
|
||||||
"videoPosition": {},
|
"videoPoints": {},
|
||||||
"videoScale": "fit",
|
"videoScale": "fit",
|
||||||
"videoMuted": false,
|
"videoMuted": false,
|
||||||
"videoSize": "small",
|
"videoSize": "small",
|
||||||
|
|
|
@ -222,7 +222,7 @@ pandora.Query = (function() {
|
||||||
|
|
||||||
fromString: function(str) {
|
fromString: function(str) {
|
||||||
var data
|
var data
|
||||||
query = Ox.unserialize(str.substr(1)),
|
query = Ox.unserialize(str),
|
||||||
sort = []
|
sort = []
|
||||||
if ('find' in query) {
|
if ('find' in query) {
|
||||||
data = parseFind(query.find || '');
|
data = parseFind(query.find || '');
|
||||||
|
@ -284,10 +284,9 @@ pandora.Query = (function() {
|
||||||
var sort = pandora.user.ui.lists[pandora.user.ui.list].sort[0],
|
var sort = pandora.user.ui.lists[pandora.user.ui.list].sort[0],
|
||||||
key = sort.key,
|
key = sort.key,
|
||||||
operator = sort.operator;
|
operator = sort.operator;
|
||||||
return '?' + Ox.serialize({
|
return pandora.user.ui.lists[pandora.user.ui.list].listView + '/?' + Ox.serialize({
|
||||||
find: constructFind(pandora.user.ui.query),
|
find: constructFind(pandora.user.ui.query),
|
||||||
sort: (operator == pandora.getSortOperator(key) ? '' : operator) + key,
|
sort: (operator == pandora.getSortOperator(key) ? '' : operator) + key
|
||||||
view: pandora.user.ui.lists[pandora.user.ui.list].listView
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
// vim: et:ts=4:sw=4:sts=4:ft=javascript
|
// vim: et:ts=4:sw=4:sts=4:ft=javascript
|
||||||
pandora.UI = (function() {
|
pandora.UI = (function() {
|
||||||
|
// fixme: why do we use '|', and not '.', as a separator?
|
||||||
return {
|
return {
|
||||||
|
// sets pandora.user.ui.key to val
|
||||||
|
// key foo|bar|baz sets pandora.user.ui.foo.bar.baz
|
||||||
|
// val null removes a key
|
||||||
set: function(/*{key: val} or key, val*/) {
|
set: function(/*{key: val} or key, val*/) {
|
||||||
var obj = Ox.makeObject(arguments);
|
var obj = Ox.makeObject(arguments);
|
||||||
Ox.forEach(obj, function(val, key) {
|
Ox.forEach(obj, function(val, key) {
|
||||||
|
|
|
@ -3,92 +3,79 @@
|
||||||
|
|
||||||
pandora.URL = (function() {
|
pandora.URL = (function() {
|
||||||
|
|
||||||
var regexps = {
|
var previousURL = '',
|
||||||
'^(|home)$': function(url) {
|
regexps = {
|
||||||
if (url == 'home' || pandora.user.ui.showHome) {
|
'^$': function(pathname, search) {
|
||||||
//$('.OxLoadingScreen').stop().remove();
|
if (!search) {
|
||||||
pandora.$ui.home = pandora.ui.home().showScreen();
|
if (pandora.user.ui.showHome) {
|
||||||
pandora.user.ui.showHome = false;
|
pandora.$ui.home = pandora.ui.home().showScreen();
|
||||||
|
}
|
||||||
|
pandora.Query.updateGroups();
|
||||||
|
} else if (/^\?url=/.test(search)) {
|
||||||
|
document.location = decodeURIComponent(search.substr(5));
|
||||||
|
} else {
|
||||||
|
pandora.Query.fromString(search);
|
||||||
|
pandora.UI.set({
|
||||||
|
section: 'items',
|
||||||
|
item: ''
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
'^home$': function(pathname, search) {
|
||||||
|
pandora.$ui.home = pandora.ui.home().showScreen();
|
||||||
pandora.Query.updateGroups();
|
pandora.Query.updateGroups();
|
||||||
},
|
},
|
||||||
'^\\?url=': function(url) {
|
'^(items|edits|texts)$': function(pathname, search) {
|
||||||
Ox.print('URL', url)
|
|
||||||
document.location = decodeURIComponent(url.substr(5));
|
|
||||||
},
|
|
||||||
'^\\?': function(url) {
|
|
||||||
pandora.Query.fromString(url);
|
|
||||||
pandora.UI.set({
|
pandora.UI.set({
|
||||||
section: 'items',
|
section: pathname
|
||||||
item: ''
|
|
||||||
});
|
});
|
||||||
},
|
|
||||||
'^(about|faq|home|news|software|terms|tour)$': function(url) {
|
|
||||||
pandora.$ui.siteDialog = pandora.ui.siteDialog(url).open();
|
|
||||||
pandora.Query.updateGroups();
|
pandora.Query.updateGroups();
|
||||||
},
|
},
|
||||||
'^(signin|signout|signup)$': function(url) {
|
'^(about|contact|faq|news|software|terms|tour)$': function(pathname, search) {
|
||||||
if ((url == 'signout') == (pandora.user.level != 'guest')) {
|
pandora.$ui.siteDialog = pandora.ui.siteDialog(pathname).open();
|
||||||
|
pandora.Query.updateGroups();
|
||||||
|
},
|
||||||
|
'^help$': function(pathname, search) {
|
||||||
|
pandora.$ui.helpDialog = pandora.ui.helpDialog().open();
|
||||||
|
pandora.Query.updateGroups();
|
||||||
|
},
|
||||||
|
'^(signin|signout|signup)$': function(pathname, search) {
|
||||||
|
if ((pathname == 'signout') == (pandora.user.level != 'guest')) {
|
||||||
pandora.$ui.accountDialog = (
|
pandora.$ui.accountDialog = (
|
||||||
pandora.user.level == 'guest'
|
pandora.user.level == 'guest'
|
||||||
? pandora.ui.accountDialog(url)
|
? pandora.ui.accountDialog(pathname)
|
||||||
: pandora.ui.accountSignoutDialog()
|
: pandora.ui.accountSignoutDialog()
|
||||||
).open();
|
).open();
|
||||||
}
|
}
|
||||||
pandora.Query.updateGroups();
|
pandora.Query.updateGroups();
|
||||||
},
|
},
|
||||||
'^preferences$': function() {
|
'^preferences$': function(pathname, search) {
|
||||||
pandora.$ui.preferencesDialog = pandora.ui.preferencesDialog().open();
|
pandora.$ui.preferencesDialog = pandora.ui.preferencesDialog().open();
|
||||||
pandora.Query.updateGroups();
|
pandora.Query.updateGroups();
|
||||||
},
|
},
|
||||||
'^help$': function() {
|
'^(calendar|calendars|clip|clips|flow|grid|list|map|maps|timelines)$': function(pathname, search) {
|
||||||
pandora.$ui.helpDialog = pandora.ui.helpDialog().open();
|
pandora.UI.set({
|
||||||
|
section: 'items',
|
||||||
|
item: ''
|
||||||
|
});
|
||||||
|
pandora.UI.set(['lists', pandora.user.ui.list, 'listView'].join('|'), pathname);
|
||||||
pandora.Query.updateGroups();
|
pandora.Query.updateGroups();
|
||||||
|
pandora.Query.fromString(search);
|
||||||
},
|
},
|
||||||
'^admin': function(url) {
|
'^[0-9A-Z]': function(pathname, search) {
|
||||||
var split = url.split('/'),
|
var split = pathname.split('/'),
|
||||||
section = new RegExp(
|
|
||||||
'^ˆ(statistics|users)$'
|
|
||||||
).exec(split[1]);
|
|
||||||
section = section ? section[0] : 'users';
|
|
||||||
pandora.UI.set({
|
|
||||||
section: 'site',
|
|
||||||
sitePage: url
|
|
||||||
});
|
|
||||||
},
|
|
||||||
'^find$': function() {
|
|
||||||
pandora.Query.fromString('?find='); // fixme: silly hack
|
|
||||||
pandora.UI.set({
|
|
||||||
section: 'items',
|
|
||||||
item: ''
|
|
||||||
});
|
|
||||||
},
|
|
||||||
'^(calendar|calendars|clips|icons|flow|map|maps|timelines)$': function(url) {
|
|
||||||
pandora.UI.set({
|
|
||||||
section: 'items',
|
|
||||||
item: ''
|
|
||||||
});
|
|
||||||
pandora.UI.set(['lists', pandora.user.ui.list, 'listView'].join('|'), url);
|
|
||||||
},
|
|
||||||
'^texts$': function() {
|
|
||||||
pandora.UI.set({
|
|
||||||
section: 'texts'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
'^[0-9A-Z]': function(url) {
|
|
||||||
var split = url.split('/'),
|
|
||||||
length = split.length,
|
|
||||||
item = split[0],
|
item = split[0],
|
||||||
|
points,
|
||||||
|
time = split.length > 1
|
||||||
|
? /[\d\.:,-]+/.exec(split[split.length - 1])
|
||||||
|
: null,
|
||||||
view = new RegExp(
|
view = new RegExp(
|
||||||
'^(' + $.map(pandora.site.itemViews, function(v) {
|
'^(' + $.map(pandora.site.itemViews, function(v) {
|
||||||
return v.id;
|
return v.id;
|
||||||
}).join('|') + ')$'
|
}).join('|') + ')$'
|
||||||
).exec(split[1]),
|
).exec(split[1]);
|
||||||
position = length > 1
|
|
||||||
? /[\d\.:-]+/.exec(split[length - 1])
|
|
||||||
: null;
|
|
||||||
view = view ? view[0]
|
view = view ? view[0]
|
||||||
: position ? pandora.user.ui.videoView
|
: time ? pandora.user.ui.videoView
|
||||||
: pandora.user.ui.itemView;
|
: pandora.user.ui.itemView;
|
||||||
pandora.UI.set(Ox.extend({
|
pandora.UI.set(Ox.extend({
|
||||||
section: 'items',
|
section: 'items',
|
||||||
|
@ -97,26 +84,92 @@ pandora.URL = (function() {
|
||||||
}, ['player', 'timeline'].indexOf(view) > -1 ? {
|
}, ['player', 'timeline'].indexOf(view) > -1 ? {
|
||||||
videoView: view
|
videoView: view
|
||||||
} : {}));
|
} : {}));
|
||||||
if (position) {
|
if (time) {
|
||||||
split[length - 1] = position[0].split('-').map(function(point, i) {
|
points = time[0].split(',');
|
||||||
// fixme: this is duplicated, see Ox.VideoPlayer() parsePositionInput()
|
if (points.length == 2) {
|
||||||
|
points = Ox.flatten([points[0], points[1].split('-')]);
|
||||||
|
if (points[2] == '') {
|
||||||
|
points[2] = '-1';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// fixme: this is duplicated, see Ox.VideoPlayer() parsePositionInput()
|
||||||
|
points = points.map(function(point, i) {
|
||||||
var parts = point.split(':').reverse();
|
var parts = point.split(':').reverse();
|
||||||
while (parts.length > 3) {
|
while (parts.length > 3) {
|
||||||
parts.pop();
|
parts.pop();
|
||||||
}
|
}
|
||||||
point = parts.reduce(function(prev, curr, i) {
|
return parts.reduce(function(prev, curr, i) {
|
||||||
return prev + (parseFloat(curr) || 0) * Math.pow(60, i);
|
return prev + (parseFloat(curr) || 0) * Math.pow(60, i);
|
||||||
}, 0);
|
}, 0);
|
||||||
i == 0 && pandora.UI.set(['videoPosition', item].join('|'), point);
|
});
|
||||||
return Ox.formatDuration(point, 3).replace(/\.000$/, '');
|
pandora.UI.set('videoPoints|' + item, {
|
||||||
}).join('-');
|
'in': points.length == 1 ? 0 : points[points.length - 2],
|
||||||
pandora.URL.replace(split.join('/'))
|
out: points.length == 1 ? 0 : points[points.length - 1],
|
||||||
|
position: points[0],
|
||||||
|
});
|
||||||
|
points = points.map(function(point) {
|
||||||
|
return point == -1 ? '' : Ox.formatDuration(point, 3).replace(/\.000$/, '');
|
||||||
|
});
|
||||||
|
split[split.length - 1] = points[0] + (
|
||||||
|
points.length == 1 ? '' : ',' + points[1] + '-' + points[2]
|
||||||
|
);
|
||||||
|
pandora.URL.replace(split.join('/'));
|
||||||
|
} else if (!pandora.user.ui.videoPoints[item]) {
|
||||||
|
pandora.UI.set('videoPoints|' + item, {
|
||||||
|
'in': 0, out: 0, position: 0
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
'.*': function(pathname, search) {
|
||||||
|
var query = search || 'find=' + pathname;
|
||||||
|
pandora.Query.fromString(query);
|
||||||
|
pandora.URL.replace('?' + query);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function saveURL() {
|
||||||
|
previousURL = document.location.pathname + document.location.search;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
||||||
|
parse: function() {
|
||||||
|
var pathname = document.location.pathname.substr(1),
|
||||||
|
search = document.location.search.substr(1);
|
||||||
|
if (/\/$/.test(pathname)) {
|
||||||
|
pathname = pathname.substr(0, pathname.length - 1);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
var url = document.location.pathname.substr(1)
|
||||||
|
+ document.location.search
|
||||||
|
+ document.location.hash;
|
||||||
|
*/
|
||||||
|
Ox.forEach(regexps, function(fn, re) {
|
||||||
|
re = new RegExp(re);
|
||||||
|
if (re.test(pathname)) {
|
||||||
|
Ox.print('URL re ' + re);
|
||||||
|
fn(pathname, search);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
pandora.user.ui.showHome = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
push: function(title, url) {
|
||||||
|
if (arguments.length == 1) { // fixme: remove later
|
||||||
|
url = title;
|
||||||
|
}
|
||||||
|
if (url[0] != '/') {
|
||||||
|
url = '/' + url;
|
||||||
|
}
|
||||||
|
saveURL();
|
||||||
|
history.pushState({}, pandora.site.site.name + (title ? ' - ' + title : ''), url);
|
||||||
|
},
|
||||||
|
|
||||||
|
pushPrevious: function() {
|
||||||
|
history.pushState({}, '', previousURL);
|
||||||
|
},
|
||||||
|
|
||||||
set: function(title, url) {
|
set: function(title, url) {
|
||||||
if (arguments.length == 1) { // fixme: remove later
|
if (arguments.length == 1) { // fixme: remove later
|
||||||
url = title;
|
url = title;
|
||||||
|
@ -128,31 +181,6 @@ pandora.URL = (function() {
|
||||||
this.update();
|
this.update();
|
||||||
},
|
},
|
||||||
|
|
||||||
parse: function() {
|
|
||||||
var url = document.location.pathname.substr(1) +
|
|
||||||
document.location.search +
|
|
||||||
document.location.hash;
|
|
||||||
Ox.forEach(regexps, function(fn, re) {
|
|
||||||
//Ox.print(url, 're', re)
|
|
||||||
re = new RegExp(re);
|
|
||||||
if (re.test(url)) {
|
|
||||||
Ox.print('URL re ' + re);
|
|
||||||
fn(url);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
push: function(title, url) {
|
|
||||||
if (arguments.length == 1) { // fixme: remove later
|
|
||||||
url = title;
|
|
||||||
}
|
|
||||||
if (url[0] != '/') {
|
|
||||||
url = '/' + url;
|
|
||||||
}
|
|
||||||
history.pushState({}, pandora.site.site.name + (title ? ' - ' + title : ''), url);
|
|
||||||
},
|
|
||||||
|
|
||||||
replace: function(title, url) {
|
replace: function(title, url) {
|
||||||
if (arguments.length == 1) { // fixme: remove later
|
if (arguments.length == 1) { // fixme: remove later
|
||||||
url = title;
|
url = title;
|
||||||
|
@ -160,6 +188,7 @@ pandora.URL = (function() {
|
||||||
if (url[0] != '/') {
|
if (url[0] != '/') {
|
||||||
url = '/' + url;
|
url = '/' + url;
|
||||||
}
|
}
|
||||||
|
saveURL();
|
||||||
history.replaceState({}, pandora.site.site.name + (title ? ' - ' + title : ''), url);
|
history.replaceState({}, pandora.site.site.name + (title ? ' - ' + title : ''), url);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -193,7 +222,7 @@ pandora.URL = (function() {
|
||||||
pandora.$ui.leftPanel.replaceElement(2, pandora.$ui.info = pandora.ui.info());
|
pandora.$ui.leftPanel.replaceElement(2, pandora.$ui.info = pandora.ui.info());
|
||||||
pandora.$ui.contentPanel.replaceElement(1, pandora.ui.item());
|
pandora.$ui.contentPanel.replaceElement(1, pandora.ui.item());
|
||||||
}
|
}
|
||||||
// fixme: should be 'editor', not 'timeline'
|
// fixme: should be 'video', not 'player'
|
||||||
if (
|
if (
|
||||||
oldUserUI.item &&
|
oldUserUI.item &&
|
||||||
['player', 'timeline'].indexOf(oldUserUI.itemView) > -1
|
['player', 'timeline'].indexOf(oldUserUI.itemView) > -1
|
||||||
|
@ -202,7 +231,7 @@ pandora.URL = (function() {
|
||||||
oldUserUI.itemView == 'player' ? 'player' : 'editor'
|
oldUserUI.itemView == 'player' ? 'player' : 'editor'
|
||||||
];
|
];
|
||||||
$item && pandora.UI.set(
|
$item && pandora.UI.set(
|
||||||
'videoPosition|' + oldUserUI.item,
|
'videoPoints|' + oldUserUI.item + '|position',
|
||||||
$item.options('position')
|
$item.options('position')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ pandora.ui.browser = function() {
|
||||||
.bindEvent({
|
.bindEvent({
|
||||||
resize: function(event, data) {
|
resize: function(event, data) {
|
||||||
pandora.user.ui.groupsSize = data;
|
pandora.user.ui.groupsSize = data;
|
||||||
$.each(pandora.$ui.groups, function(i, list) {
|
pandora.$ui.groups.forEach(function(list) {
|
||||||
list.size();
|
list.size();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -362,7 +362,8 @@ pandora.ui.folderList = function(id) {
|
||||||
});
|
});
|
||||||
pandora.URL.set('?find=' + (id == 'volumes' ? 'volume' : 'list') + ':' + data.ids[0]);
|
pandora.URL.set('?find=' + (id == 'volumes' ? 'volume' : 'list') + ':' + data.ids[0]);
|
||||||
} else {
|
} else {
|
||||||
pandora.URL.set('?find=');
|
pandora.UI.set({list: ''});
|
||||||
|
pandora.URL.set('');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
submit: function(event, data) {
|
submit: function(event, data) {
|
||||||
|
|
|
@ -58,7 +58,7 @@ pandora.ui.group = function(id) {
|
||||||
items: function(data, callback) {
|
items: function(data, callback) {
|
||||||
//if (pandora.user.ui.showGroups) {
|
//if (pandora.user.ui.showGroups) {
|
||||||
delete data.keys;
|
delete data.keys;
|
||||||
return pandora.api.find($.extend(data, {
|
return pandora.api.find(Ox.extend(data, {
|
||||||
group: id,
|
group: id,
|
||||||
query: pandora.user.ui.groupsData[i].query
|
query: pandora.user.ui.groupsData[i].query
|
||||||
}), callback);
|
}), callback);
|
||||||
|
|
|
@ -62,6 +62,7 @@ pandora.ui.home = function() {
|
||||||
})
|
})
|
||||||
.bind({
|
.bind({
|
||||||
click: function() {
|
click: function() {
|
||||||
|
pandora.URL.pushPrevious();
|
||||||
that.fadeOutScreen();
|
that.fadeOutScreen();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -124,6 +125,7 @@ pandora.ui.home = function() {
|
||||||
})
|
})
|
||||||
.bindEvent({
|
.bindEvent({
|
||||||
click: function() {
|
click: function() {
|
||||||
|
pandora.URL.pushPrevious();
|
||||||
that.fadeOutScreen();
|
that.fadeOutScreen();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,17 +1,32 @@
|
||||||
// vim: et:ts=4:sw=4:sts=4:ft=javascript
|
// vim: et:ts=4:sw=4:sts=4:ft=javascript
|
||||||
pandora.ui.item = function() {
|
pandora.ui.item = function() {
|
||||||
|
|
||||||
var that = Ox.Element();
|
var that = Ox.Element();
|
||||||
|
|
||||||
pandora.api.get({
|
pandora.api.get({
|
||||||
id: pandora.user.ui.item,
|
id: pandora.user.ui.item,
|
||||||
keys: []
|
keys: []
|
||||||
}, pandora.user.level == 'admin' && pandora.user.ui.itemView == 'info' ? 0 : -1, function(result) {
|
}, pandora.user.level == 'admin' && pandora.user.ui.itemView == 'info' ? 0 : -1, function(result) {
|
||||||
|
|
||||||
|
if (result.status.code == 200) {
|
||||||
|
// fixme: probably does not belong here
|
||||||
|
document.title = '0xDB - ' + result.data.title;
|
||||||
|
if (pandora.user.ui.videoPoints[result.data.id].out == -1) {
|
||||||
|
pandora.UI.set('videoPoints|' + result.data.id + '|out', result.data.duration);
|
||||||
|
pandora.URL.replace(
|
||||||
|
document.location.pathname
|
||||||
|
+ Ox.formatDuration(result.data.duration, 3).replace(/\.000$/, '')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (result.status.code != 200) {
|
if (result.status.code != 200) {
|
||||||
// fixme: this is quite a hack
|
// fixme: this is quite a hack
|
||||||
var title = decodeURI(pandora.user.ui.item).toLowerCase(),
|
var title = decodeURI(pandora.user.ui.item).toLowerCase(),
|
||||||
videoPosition;
|
videoPoints;
|
||||||
if (pandora.user.ui.item in pandora.user.ui.videoPosition) {
|
if (pandora.user.ui.item in pandora.user.ui.videoPoints) {
|
||||||
videoPosition = pandora.user.ui.videoPosition[pandora.user.ui.item];
|
videoPoints = pandora.user.ui.videoPoints[pandora.user.ui.item];
|
||||||
pandora.UI.set(['videoPosition', pandora.user.ui.item].join('|'), null);
|
pandora.UI.set(['videoPoints', pandora.user.ui.item].join('|'), null);
|
||||||
}
|
}
|
||||||
pandora.api.find({
|
pandora.api.find({
|
||||||
query: {
|
query: {
|
||||||
|
@ -37,8 +52,8 @@ pandora.ui.item = function() {
|
||||||
- re.exact.test(a.title) * 2000000;
|
- re.exact.test(a.title) * 2000000;
|
||||||
})[0].id;
|
})[0].id;
|
||||||
pandora.user.ui.item = '';
|
pandora.user.ui.item = '';
|
||||||
!Ox.isUndefined(videoPosition)
|
!Ox.isUndefined(videoPoints)
|
||||||
&& pandora.UI.set(['videoPosition', id].join('|'), videoPosition);
|
&& pandora.UI.set(['videoPoints', id].join('|'), videoPoints);
|
||||||
pandora.URL.set(id);
|
pandora.URL.set(id);
|
||||||
} else {
|
} else {
|
||||||
pandora.$ui.contentPanel.replaceElement(1,
|
pandora.$ui.contentPanel.replaceElement(1,
|
||||||
|
@ -52,9 +67,9 @@ pandora.ui.item = function() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (!result.data.rendered &&
|
} else if (!result.data.rendered && [
|
||||||
['clips', 'map',
|
'clips', 'map', 'player', 'timeline'
|
||||||
'player', 'timeline'].indexOf(pandora.user.ui.itemView)>-1) {
|
].indexOf(pandora.user.ui.itemView)>-1) {
|
||||||
pandora.$ui.contentPanel.replaceElement(1,
|
pandora.$ui.contentPanel.replaceElement(1,
|
||||||
Ox.Element()
|
Ox.Element()
|
||||||
.css({marginTop: '32px', fontSize: '12px', textAlign: 'center'})
|
.css({marginTop: '32px', fontSize: '12px', textAlign: 'center'})
|
||||||
|
@ -64,8 +79,10 @@ pandora.ui.item = function() {
|
||||||
+ pandora.user.ui.itemView + ' view.'
|
+ pandora.user.ui.itemView + ' view.'
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
} else if (pandora.user.ui.itemView == 'calendar') {
|
} else if (pandora.user.ui.itemView == 'calendar') {
|
||||||
pandora.$ui.contentPanel.replaceElement(1, Ox.Element().html('Calendar'));
|
pandora.$ui.contentPanel.replaceElement(1, Ox.Element().html('Calendar'));
|
||||||
|
|
||||||
} else if (pandora.user.ui.itemView == 'clips') {
|
} else if (pandora.user.ui.itemView == 'clips') {
|
||||||
var ratio = result.data.stream.aspectRatio;
|
var ratio = result.data.stream.aspectRatio;
|
||||||
Ox.print('RATIO', ratio)
|
Ox.print('RATIO', ratio)
|
||||||
|
@ -86,7 +103,7 @@ pandora.ui.item = function() {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
items: function(data, callback) {
|
items: function(data, callback) {
|
||||||
pandora.api.findAnnotations($.extend(data, {
|
pandora.api.findAnnotations(Ox.extend(data, {
|
||||||
itemQuery: {
|
itemQuery: {
|
||||||
conditions:[{
|
conditions:[{
|
||||||
key: 'id',
|
key: 'id',
|
||||||
|
@ -104,11 +121,17 @@ pandora.ui.item = function() {
|
||||||
open: function(event, data) {
|
open: function(event, data) {
|
||||||
var id = data.ids[0],
|
var id = data.ids[0],
|
||||||
item = pandora.user.ui.item,
|
item = pandora.user.ui.item,
|
||||||
position = pandora.$ui.clips.value(id, 'in');
|
points = {
|
||||||
pandora.UI.set('videoPosition|' + item, position);
|
'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.URL.set(item + '/timeline');
|
pandora.URL.set(item + '/timeline');
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
} else if (pandora.user.ui.itemView == 'info') {
|
} else if (pandora.user.ui.itemView == 'info') {
|
||||||
//Ox.print('result.data', result.data)
|
//Ox.print('result.data', result.data)
|
||||||
if (pandora.user.level == 'admin' && false) {
|
if (pandora.user.level == 'admin' && false) {
|
||||||
|
@ -239,8 +262,13 @@ pandora.ui.item = function() {
|
||||||
open: function(event, data) {
|
open: function(event, data) {
|
||||||
var id = data.ids[0],
|
var id = data.ids[0],
|
||||||
item = pandora.user.ui.item,
|
item = pandora.user.ui.item,
|
||||||
position = pandora.$ui.clips.value(id, 'in');
|
points = {
|
||||||
pandora.UI.set('videoPosition|' + item, position);
|
'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.URL.set(item + '/timeline');
|
pandora.URL.set(item + '/timeline');
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
@ -253,6 +281,7 @@ pandora.ui.item = function() {
|
||||||
.bindEvent('resize', function() {
|
.bindEvent('resize', function() {
|
||||||
pandora.$ui.map.resizeMap();
|
pandora.$ui.map.resizeMap();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
} else if (pandora.user.ui.itemView == 'statistics') {
|
} else if (pandora.user.ui.itemView == 'statistics') {
|
||||||
var stats = Ox.Container();
|
var stats = Ox.Container();
|
||||||
Ox.TreeList({
|
Ox.TreeList({
|
||||||
|
@ -262,7 +291,6 @@ pandora.ui.item = function() {
|
||||||
|
|
||||||
pandora.$ui.contentPanel.replaceElement(1, stats);
|
pandora.$ui.contentPanel.replaceElement(1, stats);
|
||||||
|
|
||||||
|
|
||||||
} else if (pandora.user.ui.itemView == 'player') {
|
} else if (pandora.user.ui.itemView == 'player') {
|
||||||
// fixme: duplicated
|
// fixme: duplicated
|
||||||
var layers = [],
|
var layers = [],
|
||||||
|
@ -285,8 +313,10 @@ pandora.ui.item = function() {
|
||||||
return '/' + pandora.user.ui.item + '/timeline64p' + i + '.png';
|
return '/' + pandora.user.ui.item + '/timeline64p' + i + '.png';
|
||||||
},
|
},
|
||||||
height: pandora.$ui.contentPanel.size(1),
|
height: pandora.$ui.contentPanel.size(1),
|
||||||
|
'in': pandora.user.ui.videoPoints[pandora.user.ui.item]['in'],
|
||||||
muted: pandora.user.ui.videoMuted,
|
muted: pandora.user.ui.videoMuted,
|
||||||
position: pandora.user.ui.videoPosition[pandora.user.ui.item] || 0,
|
out: pandora.user.ui.videoPoints[pandora.user.ui.item].out,
|
||||||
|
position: pandora.user.ui.videoPoints[pandora.user.ui.item].position,
|
||||||
scaleToFill: pandora.user.ui.videoScale == 'fill',
|
scaleToFill: pandora.user.ui.videoScale == 'fill',
|
||||||
showAnnotations: pandora.user.ui.showAnnotations,
|
showAnnotations: pandora.user.ui.showAnnotations,
|
||||||
showControls: pandora.user.ui.showControls,
|
showControls: pandora.user.ui.showControls,
|
||||||
|
@ -318,11 +348,12 @@ pandora.ui.item = function() {
|
||||||
pandora.UI.set('volume', data.volume);
|
pandora.UI.set('volume', data.volume);
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
} else if (pandora.user.ui.itemView == 'timeline') {
|
} else if (pandora.user.ui.itemView == 'timeline') {
|
||||||
var layers = [],
|
var layers = [],
|
||||||
video = {};
|
video = {};
|
||||||
$.each(pandora.site.layers, function(i, layer) {
|
pandora.site.layers.forEach(function(layer) {
|
||||||
layers[i] = $.extend({}, layer, {items: result.data.layers[layer.id]});
|
layers.push(Ox.extend({items: result.data.layers[layer.id]}, layer));
|
||||||
});
|
});
|
||||||
pandora.site.video.resolutions.forEach(function(resolution) {
|
pandora.site.video.resolutions.forEach(function(resolution) {
|
||||||
video[resolution] = Ox.range(result.data.parts).map(function(i) {
|
video[resolution] = Ox.range(result.data.parts).map(function(i) {
|
||||||
|
@ -346,10 +377,11 @@ pandora.ui.item = function() {
|
||||||
},
|
},
|
||||||
height: pandora.$ui.contentPanel.size(1),
|
height: pandora.$ui.contentPanel.size(1),
|
||||||
id: 'editor',
|
id: 'editor',
|
||||||
'in': 0,
|
'in': pandora.user.ui.videoPoints[pandora.user.ui.item]['in'],
|
||||||
layers: layers,
|
layers: layers,
|
||||||
out: 0,
|
muted: pandora.user.ui.videoMuted,
|
||||||
position: pandora.user.ui.videoPosition[pandora.user.ui.item] || 0,
|
out: pandora.user.ui.videoPoints[pandora.user.ui.item].out,
|
||||||
|
position: pandora.user.ui.videoPoints[pandora.user.ui.item].position,
|
||||||
posterFrame: parseInt(video.duration / 2),
|
posterFrame: parseInt(video.duration / 2),
|
||||||
showAnnotations: pandora.user.ui.showAnnotations,
|
showAnnotations: pandora.user.ui.showAnnotations,
|
||||||
showLargeTimeline: true,
|
showLargeTimeline: true,
|
||||||
|
@ -363,6 +395,16 @@ pandora.ui.item = function() {
|
||||||
videoSize: pandora.user.ui.videoSize,
|
videoSize: pandora.user.ui.videoSize,
|
||||||
width: pandora.$ui.document.width() - pandora.$ui.mainPanel.size(0) - 1
|
width: pandora.$ui.document.width() - pandora.$ui.mainPanel.size(0) - 1
|
||||||
}).bindEvent({
|
}).bindEvent({
|
||||||
|
points: function(data) {
|
||||||
|
pandora.UI.set('videoPoints|' + pandora.user.ui.item, {
|
||||||
|
'in': data['in'],
|
||||||
|
out: data.out,
|
||||||
|
position: pandora.user.ui.videoPoints[pandora.user.ui.item].position
|
||||||
|
});
|
||||||
|
},
|
||||||
|
position: function(data) {
|
||||||
|
pandora.UI.set('videoPoints|' + pandora.user.ui.item + '|position', data.position);
|
||||||
|
},
|
||||||
resize: function(event, data) {
|
resize: function(event, data) {
|
||||||
pandora.$ui.editor.options({
|
pandora.$ui.editor.options({
|
||||||
height: data
|
height: data
|
||||||
|
@ -413,12 +455,14 @@ pandora.ui.item = function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
*/
|
*/
|
||||||
|
|
||||||
} else if (pandora.user.ui.itemView == 'files') {
|
} else if (pandora.user.ui.itemView == 'files') {
|
||||||
pandora.$ui.contentPanel.replaceElement(1,
|
pandora.$ui.contentPanel.replaceElement(1,
|
||||||
pandora.$ui.item = Ox.FilesView({
|
pandora.$ui.item = Ox.FilesView({
|
||||||
id: result.data.id
|
id: result.data.id
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
} else if (pandora.user.ui.itemView == 'frames' || pandora.user.ui.itemView == 'posters') {
|
} else if (pandora.user.ui.itemView == 'frames' || pandora.user.ui.itemView == 'posters') {
|
||||||
pandora.$ui.contentPanel.replaceElement(1,
|
pandora.$ui.contentPanel.replaceElement(1,
|
||||||
pandora.$ui.item = pandora.ui.mediaView().bindEvent({
|
pandora.$ui.item = pandora.ui.mediaView().bindEvent({
|
||||||
|
@ -428,11 +472,15 @@ pandora.ui.item = function() {
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.data) {
|
if (result.data) {
|
||||||
var director = result.data.director ? ' ('+result.data.director.join(', ') + ')' : '';
|
var director = result.data.director ? ' ('+result.data.director.join(', ') + ')' : '';
|
||||||
pandora.$ui.total.html(result.data.title + director);
|
pandora.$ui.total.html(result.data.title + director);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return that;
|
return that;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -137,7 +137,7 @@ pandora.ui.list = function() { // fixme: remove view argument
|
||||||
pandora.URL.push(pandora.Query.toString());
|
pandora.URL.push(pandora.Query.toString());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (view == 'icons') {
|
} else if (view == 'grid') {
|
||||||
//alert(JSON.stringify(pandora.user.ui.lists[pandora.user.ui.list].selected))
|
//alert(JSON.stringify(pandora.user.ui.lists[pandora.user.ui.list].selected))
|
||||||
that = Ox.IconList({
|
that = Ox.IconList({
|
||||||
borderRadius: pandora.user.ui.icons == 'posters' ? 0 : 16,
|
borderRadius: pandora.user.ui.icons == 'posters' ? 0 : 16,
|
||||||
|
@ -268,8 +268,13 @@ pandora.ui.list = function() { // fixme: remove view argument
|
||||||
open: function(data) {
|
open: function(data) {
|
||||||
var id = data.ids[0],
|
var id = data.ids[0],
|
||||||
item = id.split('/')[0],
|
item = id.split('/')[0],
|
||||||
position = that.value(id, 'in');
|
points = {
|
||||||
pandora.UI.set('videoPosition|' + item, position);
|
'in': that.value(id, 'in'),
|
||||||
|
out: that.value(id, 'out')
|
||||||
|
};
|
||||||
|
pandora.UI.set('videoPoints|' + item, Ox.extend(points, {
|
||||||
|
position: points['in']
|
||||||
|
}));
|
||||||
pandora.URL.set(item + '/timeline');
|
pandora.URL.set(item + '/timeline');
|
||||||
},
|
},
|
||||||
openpreview: function(data) {
|
openpreview: function(data) {
|
||||||
|
@ -456,8 +461,13 @@ pandora.ui.list = function() { // fixme: remove view argument
|
||||||
open: function(data) {
|
open: function(data) {
|
||||||
var id = data.ids[0],
|
var id = data.ids[0],
|
||||||
item = pandora.$ui.clips.value(id, 'item'),
|
item = pandora.$ui.clips.value(id, 'item'),
|
||||||
position = pandora.$ui.clips.value(id, 'in');
|
points = {
|
||||||
pandora.UI.set('videoPosition|' + item, position);
|
'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.URL.set(item + '/timeline');
|
pandora.URL.set(item + '/timeline');
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
@ -517,7 +527,7 @@ pandora.ui.list = function() { // fixme: remove view argument
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (['list', 'icons'].indexOf(view) > -1) {
|
if (['list', 'grid'].indexOf(view) > -1) {
|
||||||
|
|
||||||
pandora.enableDragAndDrop(that, true);
|
pandora.enableDragAndDrop(that, true);
|
||||||
|
|
||||||
|
|
|
@ -170,7 +170,7 @@ pandora.ui.mainMenu = function() {
|
||||||
change: function(event, data) {
|
change: function(event, data) {
|
||||||
var value = data.checked[0].id;
|
var value = data.checked[0].id;
|
||||||
if (data.id == 'find') {
|
if (data.id == 'find') {
|
||||||
pandora.$ui.findSelect.selectItem(value);
|
pandora.$ui.findSelect.options({value: value});
|
||||||
} else if (data.id == 'movieview') {
|
} else if (data.id == 'movieview') {
|
||||||
var id = document.location.pathname.split('/')[1];
|
var id = document.location.pathname.split('/')[1];
|
||||||
if (value == 'info')
|
if (value == 'info')
|
||||||
|
@ -192,7 +192,7 @@ pandora.ui.mainMenu = function() {
|
||||||
} else if (data.id == 'sortmovies') {
|
} else if (data.id == 'sortmovies') {
|
||||||
var operator = pandora.getSortOperator(value);
|
var operator = pandora.getSortOperator(value);
|
||||||
pandora.$ui.mainMenu.checkItem('sortMenu_ordermovies_' + (operator == '+' ? 'ascending' : 'descending'));
|
pandora.$ui.mainMenu.checkItem('sortMenu_ordermovies_' + (operator == '+' ? 'ascending' : 'descending'));
|
||||||
pandora.$ui.sortSelect.selectItem(value);
|
pandora.$ui.sortSelect.options({value: value});
|
||||||
pandora.$ui.list.options({
|
pandora.$ui.list.options({
|
||||||
sort: [{key: value, operator: operator}]
|
sort: [{key: value, operator: operator}]
|
||||||
});
|
});
|
||||||
|
@ -208,20 +208,26 @@ pandora.ui.mainMenu = function() {
|
||||||
pandora.$ui.item.reload();
|
pandora.$ui.item.reload();
|
||||||
}
|
}
|
||||||
$list = pandora.$ui.browser;
|
$list = pandora.$ui.browser;
|
||||||
} else if (pandora.user.ui.lists[pandora.user.ui.list].listView == 'icons') {
|
} else if (pandora.user.ui.lists[pandora.user.ui.list].listView == 'grid') {
|
||||||
$list = pandora.$ui.list
|
$list = pandora.$ui.list;
|
||||||
}
|
}
|
||||||
$list && $list.options({
|
$list && $list.options({
|
||||||
borderRadius: value == 'posters' ? 0 : pandora.user.ui.item ? 8 : 16,
|
borderRadius: value == 'posters' ? 0 : pandora.user.ui.item ? 8 : 16,
|
||||||
defaultRatio: value == 'posters' ? 5/8 : 1
|
defaultRatio: value == 'posters' ? 5/8 : 1
|
||||||
}).reloadList(true);
|
}).reloadList(true);
|
||||||
} else if (data.id == 'viewmovies') {
|
} else if (data.id == 'viewmovies') {
|
||||||
url('#view=' + value);
|
pandora.UI.set(['lists', pandora.user.ui.list, 'listView'].join('|'), value);
|
||||||
|
pandora.$ui.viewSelect.options({value: value});
|
||||||
|
pandora.$ui.contentPanel.replaceElement(1, pandora.$ui.list = pandora.ui.list());
|
||||||
|
pandora.URL.push('/' + value + '/' + document.location.search);
|
||||||
|
|
||||||
|
//pandora.URL.set('/' + value + '/' + document.location.search);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
click: function(event, data) {
|
click: function(event, data) {
|
||||||
if (data.id == 'home') {
|
if (data.id == 'home') {
|
||||||
pandora.$ui.home = pandora.ui.home().fadeInScreen();
|
pandora.$ui.home = pandora.ui.home().fadeInScreen();
|
||||||
|
pandora.URL.push('home');
|
||||||
} else if (['about', 'news', 'tour', 'faq', 'tos', 'contact', 'software'].indexOf(data.id) > -1) {
|
} else if (['about', 'news', 'tour', 'faq', 'tos', 'contact', 'software'].indexOf(data.id) > -1) {
|
||||||
pandora.$ui.siteDialog = pandora.ui.siteDialog(data.id).open();
|
pandora.$ui.siteDialog = pandora.ui.siteDialog(data.id).open();
|
||||||
pandora.URL.push(data.id);
|
pandora.URL.push(data.id);
|
||||||
|
|
|
@ -52,6 +52,7 @@ pandora.ui.siteDialog = function(section) {
|
||||||
}).bindEvent({
|
}).bindEvent({
|
||||||
click: function() {
|
click: function() {
|
||||||
$dialog.close();
|
$dialog.close();
|
||||||
|
pandora.URL.pushPrevious();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
|
|
|
@ -20,16 +20,17 @@ pandora.ui.viewSelect = function() {
|
||||||
margin: '4px 0 0 4px'
|
margin: '4px 0 0 4px'
|
||||||
})
|
})
|
||||||
.bindEvent({
|
.bindEvent({
|
||||||
change: !pandora.user.ui.item ? function(event, data) {
|
change: !pandora.user.ui.item ? function(data) {
|
||||||
var id = data.selected[0].id;
|
var view = data.selected[0].id;
|
||||||
pandora.$ui.mainMenu.checkItem('viewMenu_movies_' + id);
|
pandora.$ui.mainMenu.checkItem('viewMenu_movies_' + view);
|
||||||
pandora.UI.set(['lists', pandora.user.ui.list, 'listView'].join('|'), id);
|
pandora.UI.set(['lists', pandora.user.ui.list, 'listView'].join('|'), view);
|
||||||
pandora.$ui.contentPanel.replaceElement(1, pandora.$ui.list = pandora.ui.list());
|
pandora.$ui.contentPanel.replaceElement(1, pandora.$ui.list = pandora.ui.list());
|
||||||
pandora.URL.push(pandora.Query.toString());
|
pandora.URL.push('/' + view + '/' + document.location.search);
|
||||||
|
// pandora.URL.set('/' + view + '/' + document.location.search);
|
||||||
} : function(event, data) {
|
} : function(event, data) {
|
||||||
var id = data.selected[0].id;
|
var view = data.selected[0].id;
|
||||||
//pandora.UI.set({itemView: id});
|
//pandora.UI.set({itemView: id});
|
||||||
pandora.URL.set(pandora.user.ui.item + '/' + id);
|
pandora.URL.set(pandora.user.ui.item + '/' + view);
|
||||||
// pandora.$ui.contentPanel.replaceElement(1, pandora.$ui.item = pandora.ui.item());
|
// pandora.$ui.contentPanel.replaceElement(1, pandora.$ui.item = pandora.ui.item());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue