diff --git a/pandora/0xdb.json b/pandora/0xdb.json index 4d25cd96..eb794af1 100644 --- a/pandora/0xdb.json +++ b/pandora/0xdb.json @@ -6,13 +6,13 @@ "canSeeFiles": {"guest": -1, "member": -1, "staff": 3, "admin": 4} }, "clipKeys": [ - {"id": "clip:text", "title": "Clip Text", "type": "string"}, - {"id": "clip:position", "title": "Clip Position", "type": "float"}, - {"id": "clip:duration", "title": "Clip Duration", "type": "float"}, - {"id": "clip:hue", "title": "Clip Hue", "type": "hue"}, - {"id": "clip:saturation", "title": "Clip Saturation", "type": "float"}, - {"id": "clip:lightness", "title": "Clip Lightness", "type": "float"}, - {"id": "clip:volume", "title": "Clip Volume", "type": "float"} + {"id": "clip:text", "title": "Text", "type": "string"}, + {"id": "clip:position", "title": "Position", "type": "float"}, + {"id": "clip:duration", "title": "Duration", "type": "float"}, + {"id": "clip:hue", "title": "Hue", "type": "hue"}, + {"id": "clip:saturation", "title": "Saturation", "type": "float"}, + {"id": "clip:lightness", "title": "Lightness", "type": "float"}, + {"id": "clip:volume", "title": "Volume", "type": "float"} ], "groups": [ {"id": "director", "title": "Director", "type": "string"}, @@ -29,7 +29,7 @@ ], "itemKeys": [ { - "id": "all", + "id": "*", "title": "All", "type": "text", "find": true @@ -543,7 +543,13 @@ "preferences": {}, "ui": { "annotationsSize": 256, - "find": {"index": -1, "key": "", "value": ""}, + "columns": { + "Colors": { + "columns": ["title", "director", "country", "year", "hue", "saturation", "brightness"], + "columnWidth": {} + } + }, + "find": {"conditions": [], "operator": "&"}, "groups": [ {"id": "director", "sort": [{"key": "items", "operator": "-"}]}, {"id": "country", "sort": [{"key": "items", "operator": "-"}]}, @@ -555,20 +561,15 @@ "icons": "posters", "infoIconSize": 256, "item": "", + "itemSort": [{"key": "clip:position", "operator": ""}], "itemView": "info", "list": "", - "lists": { - "": { - "columns": ["title", "director", "country", "year", "language", "runtime", "genre"], - "columnWidth": {}, - "listView": "grid", - "selected": [], - "sort": [ - {"key": "director", "operator": ""} - ] - } - }, - "query": {"conditions": [], "operator": ""}, + "listColumns": ["title", "director", "country", "year", "language", "runtime", "genre"], + "listColumnWidth": {}, + "listSelection": [], + "listSort": [{"key": "director", "operator": ""}], + "listView": "grid", + "lists": {}, "section": "items", "showAnnotations": true, "showControls": true, @@ -586,8 +587,8 @@ } }, "showSidebar": true, + "showSitePosters": false, "sidebarSize": 256, - "sitePage": "home", "theme": "modern", "videoPoints": {}, "videoScale": "fit", diff --git a/pandora/item/managers.py b/pandora/item/managers.py index 429de901..fbd5f9b9 100644 --- a/pandora/item/managers.py +++ b/pandora/item/managers.py @@ -23,10 +23,10 @@ def parseCondition(condition): } ... ''' - k = condition.get('key', 'all') + k = condition.get('key', '*') k = {'id': 'itemId'}.get(k, k) if not k: - k = 'all' + k = '*' v = condition['value'] op = condition.get('operator') if not op: @@ -192,7 +192,7 @@ class ItemManager(Manager): return QuerySet(self.model) def filter_list(self, qs, l, user): - if l != "all": + if l != "*": l = l.split(":") only_public = True if not user.is_anonymous(): diff --git a/pandora/item/models.py b/pandora/item/models.py index 468d5f37..2c4440fc 100644 --- a/pandora/item/models.py +++ b/pandora/item/models.py @@ -499,7 +499,7 @@ class Item(models.Model): elif key['type'] == 'layer': qs = Annotation.objects.filter(layer__name=i, item=self).order_by('start') save(i, '\n'.join([l.value for l in qs])) - elif i != 'all' and i not in self.facet_keys: + elif i != '*' and i not in self.facet_keys: value = self.get(i) if isinstance(value, list): value = u'\n'.join(value) diff --git a/pandora/urls.py b/pandora/urls.py index fe53cc5b..4b6c3457 100644 --- a/pandora/urls.py +++ b/pandora/urls.py @@ -50,6 +50,7 @@ urlpatterns += patterns('', (r'^[A-Z0-9].*$', 'app.views.index'), (r'^[a-z0-9].+$', 'app.views.index'), (r'^$', 'app.views.index'), + (r'^.*$', 'app.views.index'), ) urlpatterns += patterns('django.views.generic.simple', diff --git a/static/js/pandora.js b/static/js/pandora.js index 1dc27b63..a28bd067 100644 --- a/static/js/pandora.js +++ b/static/js/pandora.js @@ -61,6 +61,7 @@ Ox.load({ findKeys: Ox.map(data.site.itemKeys, function(key) { return key.find ? key : null; }), + itemsSection: pandora.site.itemName.plural.toLowerCase(), sectionFolders: { items: [ {id: 'personal', title: 'Personal Lists'}, @@ -79,22 +80,32 @@ Ox.load({ {id: 'featured', title: 'Featured Texts', showBrowser: false} ] }, - sortKeys: Ox.map(data.site.itemKeys, function(key) { + sortKeys: Ox.map(pandora.site.itemKeys, function(key) { return key.columnWidth ? Ox.extend(key, { operator: pandora._getSortOperator(key.type) }) : null; }) }); + + pandora.site.listSettings = {}; + Ox.map(pandora.site.user.ui, function(val, key) { + if (/^list[A-Z]/.test(key)) { + pandora.site.listSettings[key] = key[0].toLowerCase() + key.substr(1); + } + }); + if (Ox.isEmpty(pandora.user.ui.lists)) { + var listSettings = {}; + Ox.forEach(pandora.site.listSettings, function(listSetting, setting) { + listSettings[listSetting] = pandora.site.user.ui[setting]; + }); + pandora.UI.set('lists|', listSettings); + } + Ox.extend(pandora.user, { sectionElement: 'buttons', - selectedMovies: [], + selectedMovies: [], // fixme: used for what? videoFormat: Ox.UI.getVideoFormat(pandora.site.video.formats) }); - // fixme: this should not happen - if (!pandora.user.ui.lists[pandora.user.ui.list]) { - Ox.print('THIS SHOULD NOT HAPPEN', pandora.site.user.ui.lists['']) - pandora.user.ui.lists[pandora.user.ui.list] = pandora.site.user.ui.lists['']; - } if (data.user.level == 'guest' && $.browser.mozilla) { pandora.user.ui.theme = 'classic'; @@ -106,78 +117,7 @@ Ox.load({ // set up url controller - var itemsName = pandora.site.itemName.plural.toLowerCase(), - sortKeys = {}, spanType = {}, views = {}; - views[itemsName] = { - list: Ox.merge( - // 'grid' is the default view - ['grid'], - Ox.map(pandora.site.listViews, function(view) { - return view.id == 'grid' ? null : view.id; - }) - ), - item: Ox.merge( - // 'info' is the default view, pandora.user.ui.videoView - // is the default view if there is a duration - ['info', pandora.user.ui.videoView], - pandora.site.itemViews.map(function(view) { - return [ - 'info', pandora.user.ui.videoView - ].indexOf(view.id) > -1 ? null : view.id; - }) - ) - }; - sortKeys[itemsName] = {list: {}, item: {}}; - views[itemsName].list.forEach(function(view) { - sortKeys[itemsName].list[view] = Ox.merge( - pandora.isClipView(view) ? Ox.clone(pandora.site.clipKeys) : [], - // 'director' is the default sort key - [Ox.getObjectById(pandora.site.sortKeys, 'director')], - Ox.map(pandora.site.sortKeys, function(key) { - return key.id == 'director' ? null : key; - }) - ); - }); - views[itemsName].item.forEach(function(view) { - if (pandora.isClipView(view, true)) { - sortKeys[itemsName].item[view] = Ox.merge( - // 'clip:position' is the default sort key - [Ox.getObjectById(pandora.site.clipKeys, 'clip:position')], - Ox.map(pandora.site.clipKeys, function(key) { - return key.id == 'clip:position' ? null : key; - }) - ); - } - }); - spanType[itemsName] = { - list: { - map: 'location', - calendar: 'date' - }, - item: { - video: 'duration', - timeline: 'duration', - map: 'location', - calendar: 'date' - } - }; - - pandora._URL = Ox.URL({ - findKeys: pandora.site.findKeys, - getItem: pandora.getItemByIdOrTitle, - getSpan: pandora.getMetadataByIdOrName, - pages: [ - 'about', 'contact', 'faq', 'help', 'home', 'news', - 'preferences', 'signin', 'signout', 'signup', - 'software', 'terms', 'tour' - ], - sortKeys: sortKeys, - spanType: spanType, - types: [pandora.site.itemName.plural.toLowerCase(), 'edits', 'texts'], - views: views - }); - - pandora.URL.parse(function() { + pandora.URL.init().parse(function() { Ox.UI.hideLoadingScreen(); diff --git a/static/js/pandora/UI.js b/static/js/pandora/UI.js index 2521aabb..4dd7fe7e 100644 --- a/static/js/pandora/UI.js +++ b/static/js/pandora/UI.js @@ -1,38 +1,63 @@ // vim: et:ts=4:sw=4:sts=4:ft=javascript pandora.UI = (function() { - // fixme: why do we use '|', and not '.', as a separator? - var previousUI = {}; - return { - // sets pandora.user.ui.key to val - // key foo|bar|baz sets pandora.user.ui.foo.bar.baz - // val null removes a key - getPrevious: function() { - return previousUI; - }, - set: function(/*{key: val} or key, val*/) { - var obj = Ox.makeObject(arguments); - previousUI = Ox.clone(pandora.user.ui, true); - Ox.forEach(obj, function(val, key) { - Ox.print('UI.set key', key, 'val', val); - var i = 0, - keys = key.split('|'), - ui = pandora.user.ui; - while (i < keys.length - 1) { - ui = ui[keys[i]]; - i++; - } - if (ui[keys[i]] !== val) { - if (val === null) { - delete ui[keys[i]] - } else { - ui[keys[i]] = val; - } + // fixme: "|" as separator doesn't buy us much, use "." + var self = {}, that = {}; + self.previousUI = {}; + // sets pandora.user.ui.key to val + // key foo|bar|baz sets pandora.user.ui.foo.bar.baz + // (we have to use '|' as a separator since list names may contain '.') + // val null removes a key + that.getPrevious = function(key) { + return !key ? self.previousUI : self.previousUI[key]; + }; + that.set = function(/*{key: val} or key, val*/) { + var obj = Ox.makeObject(arguments), + set = {}; + self.previousUI = Ox.clone(pandora.user.ui, true); + Ox.forEach(obj, function(val, key) { + var listSettings = pandora.site.listSettings + if (key == 'list' && !pandora.user.ui.lists[val]) { + // add default list settings + obj['lists|' + val] = {}; + Ox.forEach(listSettings, function(listSetting, setting) { + obj['lists|' + val][listSetting] = pandora.site.user.ui[setting]; + }); + } else if (Object.keys(listSettings).indexOf(key) > -1) { + // add list setting + obj['lists|' + pandora.user.ui.list + '|' + listSettings[key]] = val; + } else if ( + key == 'itemView' + && ['video', 'timeline'].indexOf(val) > -1 + && !pandora.user.ui.videoPoints[pandora.user.ui.item] + ) { + // add default videoPoints + obj['videoPoints|' + pandora.user.ui.item] = {'in': 0, out: 0, position: 0}; + } + }); + Ox.forEach(obj, function(val, key) { + var i = 0, + keys = key.split('|'), + ui = pandora.user.ui; + while (i < keys.length - 1) { + ui = ui[keys[i]]; + i++; + } + if (!Ox.isEqual(ui[keys[i]], val)) { + if (val === null) { + delete ui[keys[i]] } else { - delete obj[key]; + ui[keys[i]] = val; } + set[key] = val; + } + }); + if (Ox.len(set)) { + Ox.forEach(set, function(val, key) { + Ox.Event.trigger(key, val); }); - Ox.len(obj) && pandora.api.setUI(obj); + pandora.api.setUI(set); } - } + }; + return that; }()); diff --git a/static/js/pandora/URL.js b/static/js/pandora/URL.js index e237fe5f..081539b0 100644 --- a/static/js/pandora/URL.js +++ b/static/js/pandora/URL.js @@ -1,237 +1,366 @@ // vim: et:ts=4:sw=4:sts=4:ft=javascript - -/* -FIXME: -we may want slashes in list names, and ampersands in queries - -*/ - pandora.URL = (function() { - var previousURL = '', - regexps = { - '^$': function(pathname, search, callback) { - if (/^\?url=/.test(search)) { - document.location = decodeURIComponent(search.substr(5)); + var self = {}, that = {}; + + /* + function foundItem() { + pandora.UI.set(Ox.extend({ + section: 'items', + item: item, + itemView: view + }, ['video', 'timeline'].indexOf(view) > -1 ? { + videoView: view + } : {})); + if (time) { + points = time[0].split(','); + if ( + points.length == 2 + && (points = Ox.flatten([points[0], points[1].split('-')]))[2] == '' + ) { + pandora.api.get({ + id: item, + keys: ['duration'] + }, function(result) { + points[2] = result.data.duration.toString(); + foundTime(); + }); + } else { + foundTime(); + } + } else { + if (!pandora.user.ui.videoPoints[item]) { + pandora.UI.set('videoPoints|' + item, { + 'in': 0, out: 0, position: 0 + }); + } + foundTime(); + } + function foundTime() { + if (time) { + // fixme: this is duplicated, see Ox.VideoPlayer() parsePositionInput() + points = points.map(function(point, i) { + var parts = point.split(':').reverse(); + while (parts.length > 3) { + parts.pop(); + } + return parts.reduce(function(prev, curr, i) { + return prev + (parseFloat(curr) || 0) * Math.pow(60, i); + }, 0); + }); + pandora.UI.set('videoPoints|' + item, { + 'in': points.length == 1 ? 0 : points[points.length - 2], + 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('/')); + // on page load, we have to check if the item is in the previously selected list + // if it is not, the movie browser has to be reloaded + if (pandora.user.ui.list) { + pandora.user.ui.query = { + conditions: [{key: 'list', value: pandora.user.ui.list, operator: ''}], + operator: '&' + }; + pandora.api.find({ + query: pandora.user.ui.query, + positions: [pandora.user.ui.item], + sort: [{key: 'id', operator: ''}] + }, function(result) { + if (Ox.isUndefined(result.data.positions[pandora.user.ui.item])) { + pandora.UI.set({list: ''}); + pandora.user.ui.query = {conditions:[], operator: '&'}; + } + callback(); + }); + } else { + callback(); + } + } + } + */ + + function everyCondition(conditions, key, operator) { + // If every condition has the given key and operator + // (excluding conditions where all subconditions match) + // returns true, otherwise false + return Ox.every(conditions, function(condition) { + return condition.key == key && condition.operator == operator; + }); + } + + function getFindState(find, listsState, groupsState) { + // The find element is populated if exactly one condition in an & query + // has a findKey as key and "=" as operator (and all other conditions + // are either list or groups), or if all conditions in an | query have + // the same group id as key and "==" as operator + var conditions, indices, state = {index: -1, key: '*', value: ''}; + if (find.operator == '&') { + // number of conditions that are not list or groups + conditions = find.conditions.length + - (listsState != '') + - groupsState.filter(function(group) { + return group.index > -1; + }).length; + // indices of non-advanced find queries + indices = Ox.map(pandora.site.findKeys, function(findKey) { + var index = oneCondition(find.conditions, findKey.id, '='); + return index > -1 ? index : null; + }); + state = conditions == 1 && indices.length == 1 ? { + index: indices[0], + key: find.conditions[indices[0]].key, + value: decodeURIComponent(find.conditions[indices[0]].value) + } : { + index: -1, + key: conditions == 0 && indices.length == 0 ? '*' : 'advanced', + value: '' + }; + } else { + state = { + index: -1, + key: 'advanced', + value: '' + }; + Ox.forEach(pandora.user.ui.groups, function(key) { + if (everyCondition(find.conditions, key, '==')) { + state.key = '*'; + return false; + } + }); + } + return state; + } + + function getGroupsState(find) { + // A group is selected if exactly one condition in an & query or every + // condition in an | query has the group id as key and "==" as operator + return pandora.user.ui.groups.map(function(group) { + // FIXME: cant index be an empty array, instead of -1? + var key = group.id, + state = {index: -1, find: Ox.clone(find, true), selected: []}; + if (find.operator == '&') { + // include conditions where all subconditions match + state.index = oneCondition(find.conditions, key, '==', true); + if (state.index > -1) { + state.selected = find.conditions[state.index].conditions + ? find.conditions[state.index].conditions.map(function(condition) { + return condition.value; + }) + : [find.conditions[state.index].value]; + } + } else { + if (everyCondition(find.conditions, key, '==')) { + state.index = Ox.range(find.conditions.length); + state.selected = find.conditions.map(function(condition) { + return condition.value; + }); + } + } + if (state.selected.length) { + if (Ox.isArray(state.index)) { + // every condition in an | query matches this group + state.find = {conditions: [], operator: ''}; } else { - if (!search && pandora.user.ui.showHome) { - pandora.$ui.home = pandora.ui.home().showScreen(); - Ox.print('LIST', pandora.user.ui.list) - pandora.user.ui.list && pandora.Query.fromString( - 'find=list:' + pandora.user.ui.list - ); - } else { - pandora.Query.fromString(search); - pandora.UI.set({ - section: 'items', - item: '' - }); - } - } - callback(); - }, - '^home$': function(pathname, search, callback) { - pandora.$ui.home = pandora.ui.home().showScreen(); - callback(); - }, - '^(items|edits|texts)$': function(pathname, search, callback) { - pandora.UI.set({ - section: pathname - }); - callback(); - }, - '^(about|contact|faq|news|software|terms|tour)$': function(pathname, search, callback) { - pandora.$ui.siteDialog = pandora.ui.siteDialog(pathname).open(); - callback(); - }, - '^help$': function(pathname, search, callback) { - pandora.$ui.helpDialog = pandora.ui.helpDialog().open(); - callback(); - }, - '^(signin|signout|signup)$': function(pathname, search, callback) { - if ((pathname == 'signout') == (pandora.user.level != 'guest')) { - pandora.$ui.accountDialog = ( - pandora.user.level == 'guest' - ? pandora.ui.accountDialog(pathname) - : pandora.ui.accountSignoutDialog() - ).open(); - } - callback(); - }, - '^preferences$': function(pathname, search, callback) { - pandora.$ui.preferencesDialog = pandora.ui.preferencesDialog().open(); - callback(); - }, - '^(calendar|calendars|clip|clips|flow|grid|list|map|maps|timelines)$': function(pathname, search, callback) { - pandora.UI.set({ - section: 'items', - item: '' - }); - pandora.UI.set('lists|' + pandora.user.ui.list + '|listView', pathname); - pandora.Query.fromString(search); - callback(); - }, - '.*': function(pathname, search, callback) { - var split = pathname.split('/'), - item = decodeURI(split[0]), - points, - time = split.length > 1 - ? /[\d\.:,-]+/.exec(split[split.length - 1]) - : null, - view = new RegExp( - '^(' + pandora.site.itemViews.map(function(v) { - return v.id; - }).join('|') + ')$' - ).exec(split[1]); - view = view ? view[0] - : time ? pandora.user.ui.videoView - : pandora.user.ui.itemView; - pandora.api.get({id: item, keys: ['id']}, function(result) { - if (result.status.code == 200) { - foundItem(); - } else { - pandora.api.find({ - query: { - conditions: [{key: 'title', value: item, operator: ''}], - operator: '&' - }, - sort: [{key: 'votes', operator: ''}], // fixme: not all systems have "votes" - range: [0, 100], - keys: ['id', 'title', 'votes'] - }, function(result) { - if (result.data.items.length) { - var re = { - exact: new RegExp('^' + item + '$', 'i'), - word: new RegExp('\\b' + item + '\\b', 'i') - }; - item = result.data.items.sort(function(a, b) { - return (parseInt(b.votes) || 0) - + re.word.test(b.title) * 1000000 - + re.exact.test(b.title) * 2000000 - - (parseInt(a.votes) || 0) - - re.word.test(a.title) * 1000000 - - re.exact.test(a.title) * 2000000; - })[0].id; - split[0] = item; - foundItem(); - } else { - pandora.UI.set({ - section: 'items', - item: '' - }); - pandora.Query.fromString('?find=' + pathname); - pandora.URL.replace('?find=' + pathname); - callback(); - } - }); - } - }); - function foundItem() { - pandora.UI.set(Ox.extend({ - section: 'items', - item: item, - itemView: view - }, ['video', 'timeline'].indexOf(view) > -1 ? { - videoView: view - } : {})); - if (time) { - points = time[0].split(','); - if ( - points.length == 2 - && (points = Ox.flatten([points[0], points[1].split('-')]))[2] == '' - ) { - pandora.api.get({ - id: item, - keys: ['duration'] - }, function(result) { - points[2] = result.data.duration.toString(); - foundTime(); - }); - } else { - foundTime(); - } - } else { - if (!pandora.user.ui.videoPoints[item]) { - pandora.UI.set('videoPoints|' + item, { - 'in': 0, out: 0, position: 0 - }); - } - foundTime(); - } - function foundTime() { - if (time) { - // fixme: this is duplicated, see Ox.VideoPlayer() parsePositionInput() - points = points.map(function(point, i) { - var parts = point.split(':').reverse(); - while (parts.length > 3) { - parts.pop(); - } - return parts.reduce(function(prev, curr, i) { - return prev + (parseFloat(curr) || 0) * Math.pow(60, i); - }, 0); - }); - pandora.UI.set('videoPoints|' + item, { - 'in': points.length == 1 ? 0 : points[points.length - 2], - 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('/')); - // on page load, we have to check if the item is in the previously selected list - // if it is not, the movie browser has to be reloaded - if (pandora.user.ui.list) { - pandora.user.ui.query = { - conditions: [{key: 'list', value: pandora.user.ui.list, operator: ''}], - operator: '&' + // one condition in an & query matches this group + state.find.conditions.splice(state.index, 1); + if (state.find.conditions.length == 1) { + if (state.find.conditions[0].conditions) { + // unwrap single remaining bracketed query + state.find = { + conditions: state.find.conditions[0].conditions, + operator: state.find.conditions[0].operator }; - pandora.api.find({ - query: pandora.user.ui.query, - positions: [pandora.user.ui.item], - sort: [{key: 'id', operator: ''}] - }, function(result) { - if (Ox.isUndefined(result.data.positions[pandora.user.ui.item])) { - pandora.UI.set({list: ''}); - pandora.user.ui.query = {conditions:[], operator: '&'}; - } - callback(); - }); - } else { - callback(); } } } } - }; - - function saveURL() { - previousURL = document.location.pathname + document.location.search; + return state; + }); } - function updateURL() { + function getListsState(find) { + // A list is selected if exactly one condition in an & query has "list" + // as key and "==" as operator + var index, state = ''; + if (find.operator == '&') { + index = oneCondition(find.conditions, 'list', '=='); + if (index > -1) { + state = find.conditions[index].value; + } + } + return state; + } + + function getState() { + if (!pandora.user.ui.lists[pandora.user.ui.list]) { + pandora.user.ui.lists[pandora.user.ui.list] = pandora.site.user.ui.lists['']; + } + return { + type: pandora.user.ui.section == 'items' + ? pandora.site.itemsSection + : pandora.user.ui.section, + item: pandora.user.ui.item, + view: !pandora.user.ui.item + ? pandora.user.ui.lists[pandora.user.ui.list].view + : pandora.user.ui.itemView, + sort: !pandora.user.ui.item + ? pandora.user.ui.lists[pandora.user.ui.list].sort + : pandora.isClipView(pandora.user.ui.itemView) + ? pandora.user.ui.itemSort : [], + find: !pandora.user.ui.item + ? pandora.user.ui.find + : '' + }; + } + + function oneCondition(conditions, key, operator, includeSubconditions) { + // If exactly one condition has the given key and operator + // (including or excluding conditions where all subconditions match) + // returns the corresponding index, otherwise returns -1 + var indices = Ox.map(conditions, function(condition, i) { + return ( + condition.conditions + ? includeSubconditions && everyCondition(condition.conditions, key, operator) + : condition.key == key && condition.operator == operator + ) ? i : null; + }); + return indices.length == 1 ? indices[0] : -1; + } + + function setState(state) { + Ox.print('STATE:', state) var previousUI = pandora.UI.getPrevious(); + // var previousUI = Ox.clone(pandora.user.ui); Ox.Request.cancel(); $('video').each(function() { $(this).trigger('stop'); }); - pandora.URL.parse(function() { + pandora.user.ui._groupsState = getGroupsState(pandora.user.ui.find); + pandora.user.ui._findState = getFindState(pandora.user.ui.find, pandora.user.ui.list, pandora.user.ui._groupsState); + if (Ox.isEmpty(state)) { + if (pandora.user.ui.showHome) { + pandora.$ui.home = pandora.ui.home().showScreen(); + /* + Ox.print('LIST', pandora.user.ui.list) + pandora.user.ui.list && pandora.Query.fromString( + 'find=list:' + pandora.user.ui.list + ); + */ + } else { + pandora.UI.set({ + section: 'items', + item: '' + }); + } + } else if (state.page) { + if (state.page == 'home') { + //pandora.$ui.home = pandora.ui.home().showScreen(); + pandora.$ui.home = pandora.ui.home().fadeInScreen(); + } else if ([ + 'about', 'contact', 'faq', 'news', 'software', 'terms', 'tour' + ].indexOf(state.page) > -1) { + pandora.$ui.siteDialog = pandora.ui.siteDialog(state.page).open(); + } else if (state.page == 'help') { + pandora.$ui.helpDialog = pandora.ui.helpDialog().open(); + } else if (['signup', 'signin'].indexOf(state.page) > -1) { + if (pandora.user.level == 'guest') { + pandora.ui.accountDialog(state.page).open(); + } else { + pandora.URL.replace('/'); + } + } else if (['preferences', 'signout'].indexOf(state.page) > -1) { + if (pandora.user.level == 'guest') { + pandora.URL.replace('/'); + } else if (state.page == 'preferences') { + pandora.ui.preferencesDialog().open(); + } else { + pandora.ui.accountSignoutDialog().open(); + } + } else if (state.page == 'api') { + document.location.href = '/api/'; + } + } else { + pandora.UI.set({ + section: state.type == pandora.site.itemsSection ? 'items' : state.type, + item: state.item, + }); + + state.find && pandora.UI.set({ + find: state.find, + list: getListsState(state.find) + }); + + if (!pandora.user.ui.lists[pandora.user.ui.list]) { + pandora.UI.set( + 'lists|' + pandora.user.ui.list, + pandora.site.user.ui.lists[''] + ); + } + + if (state.view) { + pandora.UI.set( + !pandora.user.ui.item + ? 'lists|' + pandora.user.ui.list + '|view' + : 'itemView', + state.view + ); + } + + pandora.user.ui._groupsState = getGroupsState(pandora.user.ui.find); + Ox.print('_groupsState =', pandora.user.ui._groupsState); + pandora.user.ui._findState = getFindState(pandora.user.ui.find, pandora.user.ui.list, pandora.user.ui._groupsState); + + if (['video', 'timeline'].indexOf(pandora.user.ui.itemView) > -1) { + if (state.span) { + pandora.UI.set('videoPoints|' + pandora.user.ui.item, { + position: state.span[0], + 'in': state.span[1] || 0, + out: state.span[2] || 0 + }); + } else if (!pandora.user.ui.videoPoints[pandora.user.ui.item]) { + pandora.UI.set('videoPoints|' + pandora.user.ui.item, { + position: 0, + 'in': 0, + out: 0 + }); + } + } + + state.sort && pandora.UI.set( + !pandora.user.ui.item + ? 'lists|' + pandora.user.ui.list + '|sort' + : 'itemSort', + state.sort + ); + + if (!pandora.$ui.appPanel) { + return; + } + if (pandora.user.ui.section != previousUI.section) { + // new section pandora.$ui.appPanel.replaceElement(1, pandora.$ui.mainPanel = pandora.ui.mainPanel()); } else if (!pandora.user.ui.item && !previousUI.item) { // list to list + Ox.print('pUI', previousUI); var isClipView = pandora.isClipView(), list = pandora.user.ui.lists[pandora.user.ui.list], previousList = previousUI.lists[previousUI.list], - wasClipView = pandora.isClipView(previousList.listView); - if (list.listView != previousList.listView) { - pandora.$ui.mainMenu.checkItem('viewMenu_movies_' + list.listView); - pandora.$ui.viewSelect.options({value: list.listView}); + wasClipView = pandora.isClipView(previousList.view); + if (pandora.user.ui.list != previousUI.list) { + pandora.$ui.findElement.replaceWith(pandora.$ui.findElement = pandora.ui.findElement()); + } + if (list.view != previousList.view) { + pandora.$ui.mainMenu.checkItem('viewMenu_movies_' + list.view); + pandora.$ui.viewSelect.options({value: list.view}); if (isClipView != wasClipView) { pandora.$ui.mainMenu.replaceMenu('sortMenu', pandora.getSortMenu()); pandora.$ui.sortSelect.replaceWith(pandora.$ui.sortSelect = pandora.ui.sortSelect()); @@ -248,7 +377,84 @@ pandora.URL = (function() { pandora.$ui.sortSelect.options({value: list.sort[0].key}); } pandora.$ui.leftPanel.replaceElement(2, pandora.$ui.info = pandora.ui.info()); - if (Ox.isEqual(pandora.user.ui.query, previousUI.query)) { + if (Ox.isEqual(pandora.user.ui.find, previousUI.find)) { + pandora.$ui.contentPanel.replaceElement(1, pandora.$ui.list = pandora.ui.list()); + } else { + pandora.user.ui._groupsState.forEach(function(data, i) { + if (!Ox.isEqual(data.find, previousUI._groupsState[i].find)) { + pandora.$ui.groups[i].reloadList(); + } + }); + pandora.$ui.contentPanel.replaceElement(1, pandora.$ui.list = pandora.ui.list()); + //pandora.$ui.mainPanel.replaceElement(1, pandora.$ui.rightPanel = pandora.ui.rightPanel()); + } + // fixme: should list selection and deselection happen here? + // (home and menu may cause a list switch) + } else if (!pandora.user.ui.item || !previousUI.item) { + // list to item or item to list + pandora.$ui.leftPanel.replaceElement(2, pandora.$ui.info = pandora.ui.info()); + pandora.$ui.mainPanel.replaceElement(1, pandora.$ui.rightPanel = pandora.ui.rightPanel()); + } else { + // item to item + if (pandora.user.ui.item != previousUI.item) { + pandora.$ui.leftPanel.replaceElement(2, pandora.$ui.info = pandora.ui.info()); + } + pandora.$ui.contentPanel.replaceElement(1, pandora.ui.item()); + } + if ( + previousUI.item + && ['video', 'timeline'].indexOf(previousUI.itemView) > -1 + ) { + var $item = pandora.$ui[ + previousUI.itemView == 'video' ? 'player' : 'editor' + ]; + $item && pandora.UI.set( + 'videoPoints|' + previousUI.item + '|position', + $item.options('position') + ); + } + + } + pandora.user.ui.showHome = false; + + } + + function updateUI() { + // remove later + var previousUI = pandora.UI.getPrevious(); + Ox.Request.cancel(); + $('video').each(function() { + $(this).trigger('stop'); + }); + pandora.URL.parse(function() { + if (pandora.user.ui.section != previousUI.section) { + pandora.$ui.appPanel.replaceElement(1, pandora.$ui.mainPanel = pandora.ui.mainPanel()); + } else if (!pandora.user.ui.item && !previousUI.item) { + // list to list + var isClipView = pandora.isClipView(), + list = pandora.user.ui.lists[pandora.user.ui.list], + previousList = previousUI.lists[previousUI.list], + wasClipView = pandora.isClipView(previousList.view); + if (list.view != previousList.view) { + pandora.$ui.mainMenu.checkItem('viewMenu_movies_' + list.view); + pandora.$ui.viewSelect.options({value: list.view}); + if (isClipView != wasClipView) { + pandora.$ui.mainMenu.replaceMenu('sortMenu', pandora.getSortMenu()); + pandora.$ui.sortSelect.replaceWith(pandora.$ui.sortSelect = pandora.ui.sortSelect()); + if (isClipView && !wasClipView) { + pandora.UI.set('lists|' + pandora.user.ui.list + '|selected', []); + } + } + } + if (!Ox.isEqual(list.sort, previousList.sort)) { + pandora.$ui.mainMenu.checkItem('sortMenu_sortmovies_' + list.sort[0].key); + pandora.$ui.mainMenu.checkItem('sortMenu_ordermovies_' + (( + list.sort[0].operator || pandora.getSortOperator(list.sort[0].key) + ) == '+' ? 'ascending' : 'descending')); + pandora.$ui.sortSelect.options({value: list.sort[0].key}); + } + pandora.$ui.leftPanel.replaceElement(2, pandora.$ui.info = pandora.ui.info()); + if (Ox.isEqual(pandora.user.ui.find, previousUI.find)) { pandora.$ui.contentPanel.replaceElement(1, pandora.$ui.list = pandora.ui.list()); } else { pandora.$ui.mainPanel.replaceElement(1, pandora.$ui.rightPanel = pandora.ui.rightPanel()); @@ -281,8 +487,133 @@ pandora.URL = (function() { }); } - return { + that.init = function() { + var itemsSection = pandora.site.itemsSection, + findKeys, sortKeys = {}, spanType = {}, views = {}; + + views[itemsSection] = { + list: Ox.merge( + // listView is the default view + [pandora.user.ui.listView], + Ox.map(pandora.site.listViews, function(view) { + return view.id == pandora.user.ui.listView ? null : view.id; + }) + ), + item: Ox.merge( + // itemView is the default view, + // videoView is the default view if there is a duration + [pandora.user.ui.itemView, pandora.user.ui.videoView], + pandora.site.itemViews.map(function(view) { + return [ + 'info', pandora.user.ui.videoView + ].indexOf(view.id) > -1 ? null : view.id; + }) + ) + }; + + sortKeys[itemsSection] = {list: {}, item: {}}; + views[itemsSection].list.forEach(function(view) { + sortKeys[itemsSection].list[view] = Ox.merge( + pandora.isClipView(view) ? Ox.clone(pandora.site.clipKeys) : [], + // listSort[0].key is the default sort key + [Ox.getObjectById(pandora.site.sortKeys, pandora.user.ui.listSort[0].key)], + Ox.map(pandora.site.sortKeys, function(key) { + return key.id == pandora.user.ui.listSort[0].key ? null : key; + }) + ); + }); + views[itemsSection].item.forEach(function(view) { + if (pandora.isClipView(view, true)) { + sortKeys[itemsSection].item[view] = Ox.merge( + // itemSort[0].key is the default sort key + [Ox.getObjectById(pandora.site.clipKeys, pandora.user.ui.itemSort[0].key)], + Ox.map(pandora.site.clipKeys, function(key) { + return key.id == pandora.user.ui.itemSort ? null : key; + }) + ); + } + }); + + spanType[itemsSection] = { + list: { + map: 'location', + calendar: 'date' + }, + item: { + video: 'duration', + timeline: 'duration', + map: 'location', + calendar: 'date' + } + }; + + findKeys = Ox.merge([{id: 'list', type: 'string'}], pandora.site.itemKeys); + + self.URL = Ox.URL({ + findKeys: findKeys, + getItem: pandora.getItemByIdOrTitle, + getSpan: pandora.getMetadataByIdOrName, + pages: [ + 'about', 'api', 'contact', 'faq', 'help', 'home', 'news', + 'preferences', 'signin', 'signout', 'signup', + 'software', 'terms', 'tour' + ], + sortKeys: sortKeys, + spanType: spanType, + types: [pandora.site.itemName.plural.toLowerCase(), 'edits', 'texts'], + views: views + }); + + return that; + + }; + + // on page load, this sets the state from the URL + that.parse = function(callback) { + if (document.location.pathname.substr(0, 4) == 'url=') { + document.location.href = decodeURI(document.location.pathname.substr(4)); + } else { + self.URL.parse(function(state) { + setState(state); + callback(); + }); + } + return that; + }; + + // sets the URL to the previous URL + that.pop = function() { + self.URL.pop(); + }; + + // pushes a new URL (as string or from state) + that.push = function(url) { + Ox.print('push', arguments[0]) + if (url) { + self.URL.push(url, setState); + } else { + var state = getState(); + Ox.print('&&&&&&&', state) + self.URL.push(state); + setState(state); + } + return that; + }; + + // replaces the current URL (as string or from state) + that.replace = function(url) { + if (url) { + self.URL.replace(url, setState) + } else { + self.URL.replace(getState()); + } + return that; + }; + + return that; + + /* parse: function(callback) { var pathname = document.location.pathname.substr(1), search = document.location.search.substr(1); @@ -342,8 +673,8 @@ pandora.URL = (function() { update: function() { this.set(pandora.Query.toString()); - }, + } - }; + */ }()); diff --git a/static/js/pandora/pandora.js b/static/js/pandora/pandora.js index 029d9434..fb62d0c7 100644 --- a/static/js/pandora/pandora.js +++ b/static/js/pandora/pandora.js @@ -298,16 +298,15 @@ pandora.getGroupsSizes = function() { pandora.getInfoHeight = function() { // fixme: new, check if it can be used more - var isVideoPreview, list + var isVideoPreview if (!pandora.user.ui.item) { - list = pandora.user.ui.lists[pandora.user.ui.list]; - isVideoPreview = list.selected.length && !pandora.isClipView(list.listView); + isVideoPreview = pandora.user.ui.listSelection.length && !pandora.isClipView(); } else { - isVideoPreview = !pandora.isClipView(pandora.user.ui.itemView, true); + isVideoPreview = !pandora.isClipView(); } return pandora.user.ui.showInfo * Math.min( isVideoPreview - ? pandora.user.ui.sidebarSize / (16/9) + 16 + ? Math.round(pandora.user.ui.sidebarSize / (16/9)) + 16 : pandora.user.ui.sidebarSize, window.innerHeight - 109 // 20 menu + 24 bar + 64 (4 closed folders) + 1 resizebar ); @@ -329,7 +328,6 @@ pandora.getItemByIdOrTitle = function(str, callback) { }, function(result) { var id = ''; if (result.data.items.length) { - Ox.print('AAAAAA', result.data.items) var items = Ox.map(result.data.items, function(item) { // test if exact match or word match var sort = new RegExp('^' + str + '$', 'i').test(item.title) ? 2000000 @@ -338,7 +336,6 @@ pandora.getItemByIdOrTitle = function(str, callback) { // fixme: remove the (...|| 0) check once the backend sends correct data }); if (items.length) { - Ox.print('BBBBBB', items) id = items.sort(function(a, b) { return b.sort - a.sort; })[0].id; @@ -458,24 +455,24 @@ pandora.getMetadataByIdOrName = function(item, view, str, callback) { }; pandora.getSortMenu = function() { - var list = pandora.user.ui.lists[pandora.user.ui.list], - isClipView = pandora.isClipView(list.listView); + var ui = pandora.user.ui, + isClipView = pandora.isClipView(ui.listView); return { id: 'sortMenu', title: 'Sort', items: [ { id: 'sortmovies', title: 'Sort ' + (isClipView ? 'Clips' : pandora.site.itemName.plural) + ' by', items: [ { group: 'sortmovies', min: 1, max: 1, items: Ox.merge(isClipView ? Ox.merge(pandora.site.clipKeys.map(function(key) { return Ox.extend({ - checked: list.sort[0].key == key.id + checked: ui.listSort[0].key == key.id }, key); }), {}) : [], pandora.site.sortKeys.map(function(key) { return Ox.extend({ - checked: list.sort[0].key == key.id + checked: ui.listSort[0].key == key.id }, key); })) } ] }, { id: 'ordermovies', title: 'Order ' + (isClipView ? 'Clips' : pandora.site.itemName.plural), items: [ { group: 'ordermovies', min: 1, max: 1, items: [ - { id: 'ascending', title: 'Ascending', checked: (list.sort[0].operator || pandora.getSortOperator(list.sort[0].key)) == '+' }, - { id: 'descending', title: 'Descending', checked: (list.sort[0].operator || pandora.getSortOperator(list.sort[0].key)) == '-' } + { id: 'ascending', title: 'Ascending', checked: (ui.listSort[0].operator || pandora.getSortOperator(ui.listSort[0].key)) == '+' }, + { id: 'descending', title: 'Descending', checked: (ui.listSort[0].operator || pandora.getSortOperator(ui.listSort[0].key)) == '-' } ]} ] }, { id: 'advancedsort', title: 'Advanced Sort...', keyboard: 'shift control s' }, @@ -548,7 +545,10 @@ pandora.getVideoPartsAndPoints = function(durations, points) { }; pandora.isClipView = function(view, item) { - view = view || pandora.user.ui.lists[pandora.user.ui.list].listView; + if (arguments.length == 0) { + item = pandora.user.ui.item; + view = !item ? pandora.user.ui.listView : pandora.user.ui.itemView; + } return ( !item ? ['calendar', 'clip', 'map'] : ['calendar', 'clips', 'map'] ).indexOf(view) > -1; diff --git a/static/js/pandora/ui/backButton.js b/static/js/pandora/ui/backButton.js index 830d8425..6820375d 100644 --- a/static/js/pandora/ui/backButton.js +++ b/static/js/pandora/ui/backButton.js @@ -10,7 +10,6 @@ pandora.ui.backButton = function() { .bindEvent({ click: function() { pandora.UI.set({item: null}); - pandora.URL.update(); } }); return that; diff --git a/static/js/pandora/ui/browser.js b/static/js/pandora/ui/browser.js index e4a77a36..66a99c96 100644 --- a/static/js/pandora/ui/browser.js +++ b/static/js/pandora/ui/browser.js @@ -44,23 +44,25 @@ pandora.ui.browser = function() { draggable: true, id: 'list', item: function(data, sort, size) { - var icons = pandora.user.ui.icons, - ratio = icons == 'posters' ? data.posterRatio : 1; + var ui = pandora.user.ui, + ratio = ui.icons == 'posters' + ? (ui.showSitePoster ? 5/8 : data.posterRatio) : 1, size = size || 64; return { height: ratio <= 1 ? size : size / ratio, id: data.id, info: data[['title', 'director'].indexOf(sort[0].key) > -1 ? 'year' : sort[0].key], title: data.title + (data.director ? ' (' + data.director + ')' : ''), - url: icons == 'posters' - ? '/' + data.id + '/poster' + size + '.jpg' - : '/' + data.id + '/icon' + size + '.jpg', + url: '/' + data.id + '/' + ( + ui.icons == 'posters' + ? (ui.showSitePoster ? 'siteposter' : 'poster') : 'icon' + ) + size + '.jpg', width: ratio >= 1 ? size : size * ratio }; }, items: function(data, callback) { pandora.api.find(Ox.extend(data, { - query: pandora.user.ui.query + query: pandora.user.ui.find }), callback); }, keys: ['director', 'id', 'posterRatio', 'title', 'year'], @@ -69,7 +71,7 @@ pandora.ui.browser = function() { orientation: 'horizontal', selected: [pandora.user.ui.item], size: 64, - sort: pandora.user.ui.lists[pandora.user.ui.list].sort, + sort: pandora.user.ui.listSort, unique: 'id' }) .bindEvent({ @@ -77,8 +79,10 @@ pandora.ui.browser = function() { that.scrollToSelection(); }, select: function(data) { - pandora.UI.set('lists|' + pandora.user.ui.list + '|selected', data.ids); - pandora.URL.set(data.ids[0]); + pandora.UI.set({ + 'listSelection': data.ids, + 'item': data.ids[0] + }); }, toggle: function(data) { pandora.UI.set({showMovies: !data.collapsed}); @@ -90,6 +94,17 @@ pandora.ui.browser = function() { } }); pandora.enableDragAndDrop(that, false); + Ox.Event.bind({ + icons: function(value) { + that.options({ + borderRadius: value == 'posters' ? 0 : 8, + defaultRatio: value == 'posters' ? 5/8 : 1 + }).reloadList(true); + }, + showSitePoster: function() { + that.reloadList(true); + } + }); } that.update = function() { pandora.$ui.contentPanel.replaceElement(0, pandora.$ui.browser = pandora.ui.browser()); diff --git a/static/js/pandora/ui/contentPanel.js b/static/js/pandora/ui/contentPanel.js index 28a087e8..852ef9c3 100644 --- a/static/js/pandora/ui/contentPanel.js +++ b/static/js/pandora/ui/contentPanel.js @@ -28,6 +28,14 @@ pandora.ui.contentPanel = function() { ], orientation: 'vertical' }); + Ox.Event.bind({ + listView: function() { + that.replaceElement(1, pandora.$ui.list = pandora.ui.list()); + }, + itemView: function() { + that.replaceElement(1, pandora.$ui.item = pandora.ui.item()); + } + }); return that; }; diff --git a/static/js/pandora/ui/filter.js b/static/js/pandora/ui/filter.js index 377289b7..bab3e324 100644 --- a/static/js/pandora/ui/filter.js +++ b/static/js/pandora/ui/filter.js @@ -49,8 +49,8 @@ pandora.ui.filter = function(list) { }); } else { - pandora.user.ui.query = data.query; - pandora.URL.update(); + pandora.UI.set('query', data.query); + pandora.URL.push(); //reload(); } } diff --git a/static/js/pandora/ui/findElement.js b/static/js/pandora/ui/findElement.js index 23a8bfa8..2a33e7eb 100644 --- a/static/js/pandora/ui/findElement.js +++ b/static/js/pandora/ui/findElement.js @@ -1,8 +1,8 @@ // vim: et:ts=4:sw=4:sts=4:ft=javascript pandora.ui.findElement = function() { - var findIndex = pandora.user.ui.find.index, - findKey = pandora.user.ui.find.key, - findValue = pandora.user.ui.find.value; + var findIndex = pandora.user.ui._findState.index, + findKey = pandora.user.ui._findState.key, + findValue = pandora.user.ui._findState.value; var that = Ox.FormElementGroup({ elements: Ox.merge(pandora.user.ui.list ? [ pandora.$ui.findListSelect = Ox.Select({ @@ -78,20 +78,21 @@ pandora.ui.findElement = function() { && pandora.$ui.findListSelect.value() == 'list', key = pandora.$ui.findSelect.value(), conditions = data.value ? [{ - key: key == 'all' ? '' : key, + key: key, value: data.value, - operator: '' + operator: '=' }] : []; if (findInList) { - pandora.user.ui.query = { + pandora.UI.set('find', { conditions: Ox.merge([{ key: 'list', value: pandora.user.ui.list, - operator: '' + operator: '==' }], conditions), operator: '&' - } - data.value && findIndex == 0 && pandora.user.ui.query.conditions.reverse(); + }); + // fixme: what was this? + // data.value && findIndex == 0 && pandora.user.ui.find.conditions.reverse(); } else { if (pandora.user.ui.list) { Ox.forEach(pandora.$ui.folderList, function($list) { @@ -99,12 +100,12 @@ pandora.ui.findElement = function() { }); pandora.UI.set({list: ''}); } - pandora.user.ui.query = { + pandora.UI.set('find', { conditions: conditions, operator: '' - } + }); } - pandora.URL.set(pandora.Query.toString()); + pandora.URL.push(); } }) ]), @@ -115,7 +116,7 @@ pandora.ui.findElement = function() { margin: '4px' }); function autocompleteFunction() { - return pandora.user.ui.query.conditions.length ? function(value, callback) { + return pandora.user.ui.find.conditions.length ? function(value, callback) { var elementValue = that.value(), key = elementValue[pandora.user.ui.list ? 1 : 0], findKey = Ox.getObjectById(pandora.site.findKeys, key); diff --git a/static/js/pandora/ui/foldersList.js b/static/js/pandora/ui/foldersList.js index 51402c2b..c3b2296f 100644 --- a/static/js/pandora/ui/foldersList.js +++ b/static/js/pandora/ui/foldersList.js @@ -29,9 +29,11 @@ pandora.ui.folderList = function(id) { width: 16 }, { + /* format: function(value) { return value.split('/').join(': '); }, + */ id: 'id', operator: '+', unique: true, @@ -376,13 +378,25 @@ pandora.ui.folderList = function(id) { id != id_ && $list.options('selected', []); }); } - pandora.URL.set(data.ids.length ? '?find=list:' + data.ids[0] : ''); + // pandora.URL.push(data.ids.length ? '/list==' + data.ids[0] : '') /* pandora.UI.set({ item: '', list: data.ids.length ? data.ids[0] : '' - }); + }) + pandora.URL.push(); */ + pandora.UI.set({ + item: '', + list: data.ids.length ? data.ids[0] : '', + find: { + conditions: data.ids.length ? [ + {key: 'list', value: data.ids[0], operator: '=='} + ] : [], + operator: '&' + } + }) + pandora.URL.push(); }, submit: function(data) { data_ = {id: data.id}; diff --git a/static/js/pandora/ui/group.js b/static/js/pandora/ui/group.js index 0d769deb..0c606016 100644 --- a/static/js/pandora/ui/group.js +++ b/static/js/pandora/ui/group.js @@ -1,6 +1,5 @@ // vim: et:ts=4:sw=4:sts=4:ft=javascript pandora.ui.group = function(id) { - //Ox.print('group', id, Ox.getPositionById(pandora.user.ui.groups, id)) var i = Ox.getPositionById(pandora.user.ui.groups, id), group = Ox.getObjectById(pandora.site.groups, id), panelWidth = pandora.$ui.document.width() - (pandora.user.ui.showSidebar * pandora.user.ui.sidebarSize) - 1, @@ -32,7 +31,6 @@ pandora.ui.group = function(id) { .css({ float: 'left', width: pandora.user.ui.groupsSizes[i] - 64 - Ox.UI.SCROLLBAR_SIZE, - //background: 'red', textOverflow: 'ellipsis', overflowX: 'hidden' }) @@ -62,14 +60,14 @@ pandora.ui.group = function(id) { delete data.keys; return pandora.api.find(Ox.extend(data, { group: id, - query: pandora.user.ui.groupsData[i].query + query: pandora.user.ui._groupsState[i].find }), callback); //} else { // callback({data: {items: data.keys ? [] : 0}}); //} }, scrollbarVisible: true, - selected: pandora.user.ui.groupsData[i].selected, + selected: pandora.user.ui._groupsState[i].selected, sort: [{ key: pandora.user.ui.groups[i].sort[0].key, operator: pandora.user.ui.groups[i].sort[0].operator @@ -80,52 +78,61 @@ pandora.ui.group = function(id) { pandora.$ui.list.triggerEvent('paste', data); }, select: function(data) { + // FIXME: cant index be an empty array, instead of -1? var conditions = data.ids.map(function(value) { return { key: id, value: value, - operator: '=' + operator: '==' }; }), - index = pandora.user.ui.groupsData[i].index; + index = pandora.user.ui._groupsState[i].index, + find = Ox.clone(pandora.user.ui.find, true); if (Ox.isArray(index)) { // this group had multiple selections and the | query // was on the top level, i.e. not bracketed - pandora.user.ui.query = { + find = { conditions: conditions, - operator: conditions.length > 1 ? '|' : '' + operator: conditions.length > 1 ? '|' : '&' } } else { if (index == -1) { // this group had no selection, i.e. no query - index = pandora.user.ui.query.conditions.length; - if (pandora.user.ui.query.operator == '|') { - pandora.user.ui.query = { - conditions: [pandora.user.ui.query], + index = find.conditions.length; + if (find.operator == '|') { + find = { + conditions: [find], operator: '&' }; index = 1; } else { - pandora.user.ui.query.operator = index ? '&' : ''; + find.operator = '&'; } } if (conditions.length == 0) { - pandora.user.ui.query.conditions.splice(index, 1); - if (pandora.user.ui.query.conditions.length == 1) { - pandora.user.ui.query.operator = ''; + // nothing selected + find.conditions.splice(index, 1); + if (find.conditions.length == 1) { + find.operator = '&'; } } else if (conditions.length == 1) { - pandora.user.ui.query.conditions[index] = conditions[0]; + // one item selected + find.conditions[index] = conditions[0]; } else { - pandora.user.ui.query.conditions[index].conditions = conditions; - pandora.user.ui.query.conditions[index].operator = '|'; - delete pandora.user.ui.query.conditions[index].key; - delete pandora.user.ui.query.conditions[index].value; + // multiple items selected + find.conditions[index].conditions = conditions; + find.conditions[index].operator = '|'; + delete find.conditions[index].key; + delete find.conditions[index].value; } } + /* pandora.Query.updateGroups(); pandora.URL.push(pandora.Query.toString()); pandora.reloadGroups(i); + */ + pandora.UI.set('find', find); + pandora.URL.push(); }, sort: function(data) { Ox.print('SORT', data) @@ -154,9 +161,9 @@ pandora.ui.group = function(id) { i_ = Ox.getPositionById(pandora.user.ui.groups, id_); if (i_ == -1) { // new group was not part of old group set - if (pandora.user.ui.groupsData[i].selected.length) { + if (pandora.user.ui._groupsState[i].selected.length) { // if group with selection gets replaced, reload - pandora.user.ui.query.conditions.splice(pandora.user.ui.groupsData[i].index, 1); + pandora.user.ui.find.conditions.splice(pandora.user.ui._groupsState[i].index, 1); pandora.Query.updateGroups(); pandora.URL.push(pandora.Query.toString()); pandora.reloadGroups(i); @@ -169,9 +176,9 @@ pandora.ui.group = function(id) { // if part of the existing query works as a group selection in the new group } else { // swap two existing groups - var groupsData = Ox.clone(pandora.user.ui.groupsData[i]); - pandora.user.ui.groupsData[i] = pandora.user.ui.groupsData[i_]; - pandora.user.ui.groupsData[i_] = groupsData; + var groupsData = Ox.clone(pandora.user.ui._groupsState[i]); + pandora.user.ui._groupsState[i] = pandora.user.ui._groupsState[i_]; + pandora.user.ui._groupsState[i_] = groupsData; groups[i] = makeGroup(id_, pandora.user.ui.groups[i_].sort); groups[i_] = makeGroup(id, pandora.user.ui.groups[i].sort); pandora.UI.set({groups: groups}); @@ -187,8 +194,8 @@ pandora.ui.group = function(id) { sort: sort || [{key: group.type == 'integer' ? 'name' : 'items', operator: '-'}] }; } - function replaceGroup(i, id, query) { - // if query is passed, selected items will be derived from it + function replaceGroup(i, id, find) { + // if find is passed, selected items will be derived from it var isOuter = i % 4 == 0; pandora.$ui[isOuter ? 'browser' : 'groupsInnerPanel'].replaceElement( isOuter ? i / 2 : i - 1, @@ -202,7 +209,6 @@ pandora.ui.group = function(id) { pandora.ui.groups = function() { var $groups = []; - //pandora.user.queryGroups = []; pandora.user.ui.groups.forEach(function(group, i) { $groups[i] = pandora.ui.group(group.id); }); diff --git a/static/js/pandora/ui/home.js b/static/js/pandora/ui/home.js index 8892f571..08b74714 100644 --- a/static/js/pandora/ui/home.js +++ b/static/js/pandora/ui/home.js @@ -59,7 +59,7 @@ pandora.ui.home = function() { }) .bind({ click: function() { - pandora.URL.pushPrevious(); + pandora.URL.pop(); that.fadeOutScreen(); } }) @@ -107,7 +107,7 @@ pandora.ui.home = function() { click: function() { var folder = pandora.getListData().folder; folder && pandora.$ui.folderList[folder].options({selected: []}); - pandora.URL.set('/?find=' + $findInput.value()); + pandora.URL.push('/*=' + $findInput.value()); that.fadeOutScreen(); } }) @@ -127,7 +127,7 @@ pandora.ui.home = function() { }) .bindEvent({ click: function() { - pandora.URL.pushPrevious(); + pandora.URL.push(); that.fadeOutScreen(); } }) @@ -147,7 +147,7 @@ pandora.ui.home = function() { }) .bindEvent({ click: function() { - pandora.URL.set('/signup'); + pandora.URL.push('/signup'); that.fadeOutScreen(); } }), @@ -166,7 +166,7 @@ pandora.ui.home = function() { }) .bindEvent({ click: function() { - pandora.URL.set('/signin'); + pandora.URL.push('/signin'); that.fadeOutScreen(); } }), @@ -185,7 +185,7 @@ pandora.ui.home = function() { }) .bindEvent({ click: function() { - pandora.URL.set('/preferences'); + pandora.URL.push('/preferences'); that.fadeOutScreen(); } }), @@ -204,7 +204,7 @@ pandora.ui.home = function() { }) .bindEvent({ click: function() { - pandora.URL.set('/about'); + pandora.URL.push('/about'); that.fadeOutScreen(); } }) @@ -270,4 +270,4 @@ pandora.ui.home = function() { return that; -}; \ No newline at end of file +}; diff --git a/static/js/pandora/ui/info.js b/static/js/pandora/ui/info.js index 4b71a50d..d341b4b8 100644 --- a/static/js/pandora/ui/info.js +++ b/static/js/pandora/ui/info.js @@ -1,7 +1,10 @@ // vim: et:ts=4:sw=4:sts=4:ft=javascript pandora.ui.info = function() { - var list = pandora.user.ui.lists[pandora.user.ui.list], - id = pandora.user.ui.item || (list.selected.length ? list.selected[list.selected.length - 1] : null), + var id = pandora.user.ui.item || ( + pandora.user.ui.listSelection.length + ? pandora.user.ui.listSelection[pandora.user.ui.listSelection.length - 1] + : null + ), view = getView(), that = Ox.Element() .css({overflowX: 'hidden', overflowY: 'auto'}) @@ -13,7 +16,7 @@ pandora.ui.info = function() { }); Ox.print('INFO', view) if (view == 'list') { - that.empty().append(pandora.$ui.listInfo = pandora.ui.listInfo(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, @@ -75,7 +78,7 @@ pandora.ui.listInfo = function(data) { .attr({src: !pandora.user.ui.list ? '/static/png/icon256.png' : Ox.UI.getImageURL('symbolIcon')}) .css(getIconCSS()) .appendTo(that); - $('
').css({padding: '16px 0 16px 0', fontWeight: 'bold'}).html(!pandora.user.ui.list ? 'All Movies' : pandora.user.ui.list.replace('/', ': ')).appendTo(that); + $('
').css({padding: '16px 0 16px 0', fontWeight: 'bold'}).html(!pandora.user.ui.list ? 'All Movies' : pandora.user.ui.list.replace(':', ': ')).appendTo(that); $('
').css({textAlign: 'left'}).html(Ox.repeat('This is the list info text. ', 10)).appendTo(that); function getIconCSS() { var size = Math.round(pandora.user.ui.sidebarSize / 2); diff --git a/static/js/pandora/ui/infoView.js b/static/js/pandora/ui/infoView.js index 20f2c9b4..6ecfdfb8 100644 --- a/static/js/pandora/ui/infoView.js +++ b/static/js/pandora/ui/infoView.js @@ -1,5 +1,8 @@ pandora.ui.infoView = function(data) { + // fixme: given that currently, the info view doesn't scroll into view nicely + // when collapsing the movies browser, the info view should become a split panel + var css = { marginTop: '4px', textAlign: 'justify', @@ -10,7 +13,7 @@ pandora.ui.infoView = function(data) { margin = 16, iconSize = pandora.user.ui.infoIconSize, iconRatio = pandora.user.ui.icons == 'posters' - ? data.posterRatio : 1, + ? (pandora.user.ui.showSitePoster ? 5/8 : data.posterRatio) : 1, iconWidth = iconRatio > 1 ? iconSize : Math.round(iconSize * iconRatio), iconHeight = iconRatio < 1 ? iconSize : Math.round(iconSize / iconRatio), iconLeft = iconSize == 256 ? Math.floor((iconSize - iconWidth) / 2) : 0, @@ -39,7 +42,8 @@ pandora.ui.infoView = function(data) { $icon = Ox.Element('') .attr({ src: '/' + data.id + '/' + ( - pandora.user.ui.icons == 'posters' ? 'poster' : 'icon' + pandora.user.ui.icons == 'posters' + ? (pandora.user.ui.showSitePoster ? 'siteposter' : 'poster') : 'icon' ) + '512.jpg?' + uid }) .css({ @@ -312,7 +316,7 @@ pandora.ui.infoView = function(data) { .css(css) .html( formatKey(key) + data[key].map(function(value) { - return '' + value.source + '' + return '' + value.source + '' }).join(', ') ) .appendTo($text); @@ -353,9 +357,8 @@ pandora.ui.infoView = function(data) { function formatValue(value, key) { return (Ox.isArray(value) ? value : [value]).map(function(value) { return key ? - '' + value + '' + '' + value + '' : value; - //return key ? '' + value + '' : value; }).join(', '); } @@ -415,7 +418,7 @@ pandora.ui.infoView = function(data) { if ($browserImages.length == 0) { $browserImages = pandora.$ui.browser.find('img[src*="/' + data.id + '/"]'); } - if (pandora.user.ui.icons == 'posters') { + if (pandora.user.ui.icons == 'posters' && !pandora.user.ui.showSitePoster) { $browserImages.each(function() { var $this = $(this), size = Math.max($this.width(), $this.height()); @@ -439,7 +442,8 @@ pandora.ui.infoView = function(data) { }, pandora.user.ui.icons == 'posters' ? { source: selectedImage.source } : { - position: selectedImage.index // fixme: api slightly inconsistent, this shouldn't be "position" + // fixme: api slightly inconsistent, this shouldn't be "position" + position: selectedImage.index }), function() { // fixme: update the info (video preview) frame as well var src; @@ -496,13 +500,14 @@ pandora.ui.infoView = function(data) { that.reload = function() { var src = src = '/' + data.id + '/' + ( - pandora.user.ui.icons == 'posters' ? 'poster' : 'icon' + pandora.user.ui.icons == 'posters' + ? (pandora.user.ui.showSitePoster ? 'siteposter' : 'poster') : 'icon' ) + '512.jpg?' + Ox.uid() $icon.attr({src: src}); $reflectionIcon.attr({src: src}); iconSize = iconSize == 256 ? 512 : 256; iconRatio = pandora.user.ui.icons == 'posters' - ? data.posterRatio : 1; + ? (pandora.user.ui.showSitePoster ? 5/8 : data.posterRatio) : 1; toggleIconSize(); pandora.user.level == 'admin' && $list.replaceWith($list = renderList()); }; @@ -513,6 +518,11 @@ pandora.ui.infoView = function(data) { $data.css({height: height + 'px'}); }; + Ox.Event.bind({ + icons: that.reload, + showSitePoster: that.reload + }); + return that; } diff --git a/static/js/pandora/ui/item.js b/static/js/pandora/ui/item.js index c7b0521d..32d3c45f 100644 --- a/static/js/pandora/ui/item.js +++ b/static/js/pandora/ui/item.js @@ -10,7 +10,7 @@ pandora.ui.item = function() { if (result.status.code == 200) { // fixme: probably does not belong here - document.title = '0xDB - ' + result.data.title; + document.title = '0xDB - ' + Ox.stripTags(result.data.title); } /*if (result.status.code != 200) { @@ -38,58 +38,6 @@ pandora.ui.item = function() { ) ); - } else if (pandora.user.ui.itemView == 'calendar') { - pandora.$ui.contentPanel.replaceElement(1, Ox.Element().html('Calendar')); - - } else if (pandora.user.ui.itemView == 'clips') { - var ratio = result.data.stream.aspectRatio; - Ox.print('RATIO', ratio) - 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: '=' - }] - } - }), callback); - }, - keys: ['id', 'value', 'in', 'out'], - size: 128, - sort: pandora.user.ui.lists[pandora.user.ui.list].sort, - 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.URL.set(item + '/timeline'); - } - })); - } else if (pandora.user.ui.itemView == 'info') { //Ox.print('result.data', result.data) if (pandora.user.level == 'admin' && false) { @@ -147,100 +95,6 @@ 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(event, 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; - var ratio = data.aspectRatio, - width = size, - height = Math.round(size / ratio), - url = '/' + data.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: [], - keys: ['id', 'value', 'in', 'out', 'aspectRatio', 'item'], - size: 128, - sort: pandora.user.ui.lists[pandora.user.ui.list].sort, - 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.URL.set(item + '/timeline'); - } - }), - id: 'place', - size: 144 + Ox.UI.SCROLLBAR_SIZE - } - ], - orientation: 'horizontal' - }) - .bindEvent('resize', function() { - pandora.$ui.map.resizeMap(); - })); - } else if (pandora.user.ui.itemView == 'statistics') { var stats = Ox.Container(); Ox.TreeList({ @@ -250,6 +104,120 @@ pandora.ui.item = function() { pandora.$ui.contentPanel.replaceElement(1, stats); + } else if (pandora.user.ui.itemView == 'clips') { + var ratio = result.data.videoRatio; + Ox.print('RATIO', ratio) + 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) { + Ox.print('DATA', data) + pandora.api.findAnnotations(Ox.extend(data, { + itemQuery: { + conditions:[{ + key: 'id', + value: pandora.user.ui.item, + operator: '=' + }], + } + }), 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 = $('.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'); + } + } + })); + Ox.Event.bind({ + itemSort: function(value) { + pandora.$ui.clips.options({sort: value}); + } + }); + } else if (pandora.user.ui.itemView == 'video') { // fixme: duplicated var layers = [], @@ -416,6 +384,105 @@ 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(event, 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; + var ratio = data.aspectRatio, + width = size, + height = Math.round(size / ratio), + url = '/' + data.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: [], + keys: ['id', 'value', 'in', 'out', 'aspectRatio', 'item'], + size: 128, + sort: pandora.user.ui.lists[pandora.user.ui.list].sort, + 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.URL.set(item + '/timeline'); + } + }), + id: 'place', + size: 144 + Ox.UI.SCROLLBAR_SIZE + } + ], + orientation: 'horizontal' + }) + .bindEvent('resize', function() { + pandora.$ui.map.resizeMap(); + })); + + } else if (pandora.user.ui.itemView == 'calendar') { + pandora.$ui.contentPanel.replaceElement(1, Ox.Element().html('Calendar')); + + } else if (pandora.user.ui.itemView == 'files') { pandora.$ui.contentPanel.replaceElement(1, pandora.$ui.item = Ox.FilesView({ diff --git a/static/js/pandora/ui/list.js b/static/js/pandora/ui/list.js index 50896790..a2e8223c 100644 --- a/static/js/pandora/ui/list.js +++ b/static/js/pandora/ui/list.js @@ -1,10 +1,10 @@ // vim: et:ts=4:sw=4:sts=4:ft=javascript -pandora.ui.list = function() { // fixme: remove view argument +pandora.ui.list = function() { var that, $map, - view = pandora.user.ui.lists[pandora.user.ui.list].listView, + view = pandora.user.ui.listView, preview = false - //Ox.print('constructList', view); + if (view == 'list') { /* keys = Ox.unique(Ox.merge( @@ -75,7 +75,7 @@ pandora.ui.list = function() { // fixme: remove view argument visible: true, width: 16 }], */Ox.map(pandora.site.sortKeys, function(key) { - var position = pandora.user.ui.lists[pandora.user.ui.list].columns.indexOf(key.id); + var position = pandora.user.ui.listColumns.indexOf(key.id); return { align: ['string', 'text'].indexOf( Ox.isArray(key.type) ? key.type[0]: key.type @@ -90,7 +90,7 @@ pandora.ui.list = function() { // fixme: remove view argument type: key.type, unique: key.id == 'id', visible: position > -1, - width: pandora.user.ui.lists[pandora.user.ui.list].columnWidth[key.id] || key.columnWidth + width: pandora.user.ui.listColumnWidth[key.id] || key.columnWidth }; })/*)*/, columnsMovable: true, @@ -102,12 +102,12 @@ pandora.ui.list = function() { // fixme: remove view argument items: function(data, callback) { //Ox.print('data, pandora.Query.toObject', data, pandora.Query.toObject()) pandora.api.find(Ox.extend(data, { - query: pandora.user.ui.query + query: pandora.user.ui.find }), callback); }, scrollbarVisible: true, - selected: pandora.user.ui.lists[pandora.user.ui.list].selected, - sort: pandora.user.ui.lists[pandora.user.ui.list].sort + selected: pandora.user.ui.listSelection, + sort: pandora.user.ui.listSort }) .bindEvent({ columnchange: function(data) { @@ -133,8 +133,10 @@ pandora.ui.list = function() { // fixme: remove view argument pandora.$ui.mainMenu.checkItem('sortMenu_sortmovies_' + data.key); pandora.$ui.mainMenu.checkItem('sortMenu_ordermovies_' + (data.operator == '+' ? 'ascending' : 'descending')); pandora.$ui.sortSelect.selectItem(data.key); - pandora.UI.set(['lists', pandora.user.ui.list, 'sort'].join('|'), [{key: data.key, operator: data.operator}]); - pandora.URL.push(pandora.Query.toString()); + pandora.UI.set({ + listSort: [{key: data.key, operator: data.operator}] + }); + pandora.URL.push(); } }); } else if (view == 'grid') { @@ -145,30 +147,32 @@ pandora.ui.list = function() { // fixme: remove view argument draggable: true, id: 'list', item: function(data, sort, size) { - var icons = pandora.user.ui.icons, - ratio = icons == 'posters' ? data.posterRatio : 1; + var ui = pandora.user.ui, + ratio = ui.icons == 'posters' + ? (ui.showSitePoster ? 5/8 : data.posterRatio) : 1, size = size || 128; return { height: Math.round(ratio <= 1 ? size : size / ratio), id: data.id, info: data[['title', 'director'].indexOf(sort[0].key) > -1 ? 'year' : sort[0].key], title: data.title + (data.director.length ? ' (' + data.director.join(', ') + ')' : ''), - url: icons == 'posters' - ? '/' + data.id + '/poster' + size + '.jpg' - : '/' + data.id + '/icon' + size + '.jpg', + url: '/' + data.id + '/' + ( + ui.icons == 'posters' + ? (ui.showSitePoster ? 'siteposter' : 'poster') : 'icon' + ) + size + '.jpg', width: Math.round(ratio >= 1 ? size : size * ratio) }; }, items: function(data, callback) { //Ox.print('data, pandora.Query.toObject', data, pandora.Query.toObject()) pandora.api.find(Ox.extend(data, { - query: pandora.user.ui.query + query: pandora.user.ui.find }), callback); }, keys: ['director', 'id', 'posterRatio', 'title', 'year'], - selected: pandora.user.ui.lists[pandora.user.ui.list].selected, + selected: pandora.user.ui.listSelection, size: 128, - sort: pandora.user.ui.lists[pandora.user.ui.list].sort, + sort: pandora.user.ui.listSort, unique: 'id' }); } else if (view == 'info') { @@ -210,13 +214,13 @@ pandora.ui.list = function() { // fixme: remove view argument }, items: function(data, callback) { pandora.api.find(Ox.extend(data, { - query: pandora.user.ui.query + query: pandora.user.ui.find }), callback); }, keys: ['director', 'duration', 'id', 'posterRatio', 'title', 'year'], - selected: pandora.user.ui.lists[pandora.user.ui.list].selected, + selected: pandora.user.ui.listSelection, size: 192, - sort: pandora.user.ui.lists[pandora.user.ui.list].sort, + sort: pandora.user.ui.listSort, unique: 'id' }); } else if (view == 'maps') { @@ -243,7 +247,7 @@ pandora.ui.list = function() { // fixme: remove view argument }; }, items: function(data, callback) { - var itemQuery = pandora.user.ui.query, + 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) { @@ -259,7 +263,7 @@ pandora.ui.list = function() { // fixme: remove view argument keys: ['id', 'value', 'in', 'out', 'videoRatio'], max: 1, size: 128, - sort: pandora.user.ui.lists[pandora.user.ui.list].sort, + sort: pandora.user.ui.listSort, unique: 'id' }).bindEvent({ init: function(data) { @@ -275,7 +279,11 @@ pandora.ui.list = function() { // fixme: remove view argument pandora.UI.set('videoPoints|' + item, Ox.extend(points, { position: points['in'] })); - pandora.URL.set(item + '/timeline'); + pandora.UI.set({ + item: item, + itemView: pandora.user.ui.videoView + }); + pandora.URL.push(); }, openpreview: function(data) { var $video = $('.OxItem.OxSelected > .OxIcon > .OxVideoPlayer'); @@ -292,7 +300,7 @@ pandora.ui.list = function() { // fixme: remove view argument item = id.split('/')[0], width, height, $img = $('.OxItem.OxSelected > .OxIcon > img'), $video = $('.OxItem.OxSelected > .OxIcon > .OxVideoPlayer'); - pandora.UI.set('lists|' + pandora.user.ui.list + '|selected', [item]); + 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')), @@ -333,7 +341,7 @@ pandora.ui.list = function() { // fixme: remove view argument }, 300); } } else { - pandora.UI.set('lists|' + pandora.user.ui.list + '|selected', []); + pandora.UI.set('listSelection', []); pandora.$ui.leftPanel.replaceElement(2, pandora.$ui.info = pandora.ui.info()); $('.OxSelectedVideo').removeClass('OxSelectedVideo'); } @@ -350,7 +358,7 @@ pandora.ui.list = function() { // fixme: remove view argument video: function(range, callback) { var callback = arguments[arguments.length - 1], range = arguments.length == 2 ? arguments[0] : null, - itemQuery = pandora.user.ui.query, + itemQuery = pandora.user.ui.find, query = {conditions:[]}; //fixme: can this be in pandora.Query? dont just check for subtitles itemQuery.conditions.forEach(function(q) { @@ -364,7 +372,7 @@ pandora.ui.list = function() { // fixme: remove view argument }, range ? { keys: ['id', 'in', 'out'], range: range, - sort: pandora.user.ui.lists[pandora.user.ui.list].sort + sort: pandora.user.ui.listSort } : {}), function(result) { //Ox.print('API findAnnotations range', range, 'result', result.data); if (!range) { @@ -403,7 +411,7 @@ pandora.ui.list = function() { // fixme: remove view argument 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.query, + var itemQuery = pandora.user.ui.find, query = {conditions:[]}; return pandora.api.findPlaces(Ox.extend(data, { itemQuery: itemQuery, @@ -422,7 +430,7 @@ pandora.ui.list = function() { // fixme: remove view argument query: { conditions:[{key: 'place', value: place.id, operator:'='}] }, - itemQuery: pandora.user.ui.query + itemQuery: pandora.user.ui.find }), callback); } }); @@ -456,7 +464,7 @@ pandora.ui.list = function() { // fixme: remove view argument items: [], keys: ['id', 'value', 'in', 'out', 'videoRatio', 'item'], size: 128, - sort: pandora.user.ui.lists[pandora.user.ui.list].sort, + sort: pandora.user.ui.listSort, unique: 'id' }).bindEvent({ open: function(data) { @@ -500,7 +508,7 @@ pandora.ui.list = function() { // fixme: remove view argument }); pandora.api.findEvents({ query: '', - itemQuery: pandora.user.ui.query + itemQuery: pandora.user.ui.find }, function(result) { Ox.print(">>>>>>>", result); that.replaceElement(0, @@ -556,9 +564,7 @@ pandora.ui.list = function() { // fixme: remove view argument pandora.$ui.selected.html(pandora.ui.status('selected', data)); }, open: function(data) { - var id = data.ids[0], - title = that.value(id, 'title'); - pandora.URL.set(title, id); + pandora.UI.set({item: data.ids[0]}); }, openpreview: function(data) { pandora.requests.preview && pandora.api.cancel(pandora.requests.preview); @@ -642,7 +648,7 @@ pandora.ui.list = function() { // fixme: remove view argument }, select: function(data) { var $still, $timeline; - pandora.UI.set('lists|' + pandora.user.ui.list + '|selected', data.ids); + pandora.UI.set('listSelection', data.ids); if (data.ids.length) { pandora.$ui.mainMenu.enableItem('copy'); pandora.$ui.mainMenu.enableItem('openmovie'); @@ -674,6 +680,25 @@ pandora.ui.list = function() { // fixme: remove view argument pandora.$ui.rightPanel.replaceElement(1, pandora.$ui.contentPanel = pandora.ui.contentPanel()); }; + Ox.Event.bind({ + listSort: function(value) { + that.options({sort: value}); + } + }); + if (pandora.user.ui.listView == 'grid') { + Ox.Event.bind({ + icons: function(value) { + that.options({ + borderRadius: value == 'posters' ? 0 : 16, + defaultRatio: value == 'posters' ? 5/8 : 1 + }).reloadList(true); + }, + showSitePoster: function() { + that.reloadList(true); + } + }); + } + return that; }; diff --git a/static/js/pandora/ui/mainPanel.js b/static/js/pandora/ui/mainPanel.js index 3eef7007..b8e7f80a 100644 --- a/static/js/pandora/ui/mainPanel.js +++ b/static/js/pandora/ui/mainPanel.js @@ -16,7 +16,14 @@ pandora.ui.mainPanel = function() { } ], orientation: 'horizontal' - }) + }); + Ox.Event.bind({ + item: function(value) { + if (!value || !pandora.UI.getPrevious('item')) { + that.replaceElement(1, pandora.$ui.rightPanel = pandora.ui.rightPanel()); + } + } + }); return that; }; diff --git a/static/js/pandora/ui/menu.js b/static/js/pandora/ui/menu.js index ba1ecdbc..6c192250 100644 --- a/static/js/pandora/ui/menu.js +++ b/static/js/pandora/ui/menu.js @@ -1,7 +1,7 @@ // vim: et:ts=4:sw=4:sts=4:ft=javascript pandora.ui.mainMenu = function() { var isGuest = pandora.user.level == 'guest', - list = pandora.user.ui.lists[pandora.user.ui.list], + ui = pandora.user.ui, that = Ox.MainMenu({ extras: [ $('
').html('beta').css({marginRight: '8px', color: 'rgb(128, 128, 128)'}), @@ -30,7 +30,8 @@ pandora.ui.mainMenu = function() { { id: 'archives', title: 'Archives...', disabled: isGuest }, {}, { id: 'signup', title: 'Sign Up...', disabled: !isGuest }, - { id: 'signinsignout', title: isGuest ? 'Sign In...' : 'Sign Out...' } + isGuest ? { id: 'signin', title: 'Sign In...' } + : { id: 'signout', title: 'Sign Out...'} ] }, pandora.getListMenu(), { id: 'editMenu', title: 'Edit', items: [ @@ -50,16 +51,16 @@ pandora.ui.mainMenu = function() { { id: 'movies', title: 'View ' + pandora.site.itemName.plural, items: [ { group: 'viewmovies', min: 1, max: 1, items: pandora.site.listViews.map(function(view) { return Ox.extend({ - checked: list.listView == view.id, + checked: ui.listView == view.id, }, view); }) }, ]}, { id: 'icons', title: 'Icons', items: [ { group: 'viewicons', min: 1, max: 1, items: ['posters', 'frames'].map(function(icons) { - return {id: icons, title: Ox.toTitleCase(icons), checked: pandora.user.ui.icons == icons}; + return {id: icons, title: Ox.toTitleCase(icons), checked: ui.icons == icons}; }) }, {}, - { id: 'usesiteposter', title: 'Always Use ' + pandora.site.site.name + ' Poster' } + { id: 'showsiteposter', title: 'Always Show ' + pandora.site.site.name + ' Poster', checked: ui.showSitePoster } ] }, { id: 'columns', title: 'Columns', items: [ { id: 'loadcolumns', title: 'Load Layout...' }, @@ -71,20 +72,20 @@ pandora.ui.mainMenu = function() { { id: 'openmovie', title: ['Open ' + pandora.site.itemName.singular, 'Open ' + pandora.site.itemName.plural], items: [ { group: 'movieview', min: 1, max: 1, items: pandora.site.itemViews.map(function(view) { return Ox.extend({ - checked: pandora.user.ui.itemView == view.id, + checked: ui.itemView == view.id, }, view); }) }, ]}, { id: 'openvideo', title: 'Open Video Links', items: [ { group: 'videoview', min: 1, max: 1, items: ['player', 'editor'].map(function(view) { - return {id: view, title: Ox.toTitleCase(view), checked: pandora.user.ui.videoView == view}; + return {id: view, title: Ox.toTitleCase(view), checked: ui.videoView == view}; }) } ] }, {}, { id: 'groups', title: 'Groups', items: [ { group: 'groups', min: 5, max: 5, items: pandora.site.groups.map(function(group) { return Ox.extend({ - checked: Ox.getPositionById(pandora.user.ui.groups, group.id) > -1 + checked: Ox.getPositionById(ui.groups, group.id) > -1 }, group); }) }, {}, @@ -98,8 +99,8 @@ pandora.ui.mainMenu = function() { {}, { id: 'theme', title: 'Theme', items: [ { group: 'settheme', min: 1, max: 1, items: [ - { id: 'classic', title: 'Classic', checked: pandora.user.ui.theme == 'classic'}, - { id: 'modern', title: 'Modern', checked: pandora.user.ui.theme == 'modern' } + { id: 'classic', title: 'Classic', checked: ui.theme == 'classic'}, + { id: 'modern', title: 'Modern', checked: ui.theme == 'modern' } ]} ] } ]}, @@ -107,10 +108,10 @@ pandora.ui.mainMenu = function() { { id: 'findMenu', title: 'Find', items: [ { id: 'find', title: 'Find', items: [ { group: 'find', min: 1, max: 1, items: pandora.site.findKeys.map(function(key, i) { - var index = pandora.user.ui.find.index; + var index = ui._findState.index; return Ox.extend({ - checked: index > -1 && pandora.user.ui.query.conditions[index].key - ? pandora.user.ui.query.conditions[index].key == key.id + checked: index > -1 && ui.find.conditions[index].key + ? ui.find.conditions[index].key == key.id : key.id == 'all' }, key); }) } @@ -169,19 +170,16 @@ pandora.ui.mainMenu = function() { groups[position].sort[0].operator = operator; pandora.UI.set({groups: groups}); } else if (data.id == 'ordermovies') { - var key = pandora.user.ui.lists[pandora.user.ui.list].sort[0].key, + var key = pandora.user.ui.listSort[0].key, operator = value == 'ascending' ? '+' : '-'; - pandora.$ui.list.options({ - sort: [{key: key, operator: operator}] - }); - pandora.UI.set('lists|' + pandora.user.ui.list + '|sort', [{key: key, operator: operator}]); - //pandora.user.ui.lists[pandora.user.ui.list].sort[0] = {key: key, operator: operator}; - pandora.URL.push(pandora.Query.toString()); + pandora.UI.set({listSort: [{key: key, operator: operator}]}); } else if (data.id == 'settheme') { Ox.Theme(value); pandora.UI.set('theme', value); + } else if (data.id == 'showsiteposter') { + pandora.UI.set('showSitePoster', data.checked) } else if (Ox.startsWith(data.id, 'sortgroup')) { - var groups = Ox.clone(pandora.user.ui.groups), + var groups = Ox.clone(ui.groups), id = data.id.replace('sortgroup', ''), position = Ox.getPositionById(groups, id), type = Ox.getObjectById(pandora.site.groups, id).type, @@ -194,52 +192,21 @@ pandora.ui.mainMenu = function() { groups[position].sort[0].key = key; pandora.UI.set({groups: groups}); } else if (data.id == 'sortmovies') { - pandora.UI.set( - 'lists|' + pandora.user.ui.list + '|sort', - [{key: value, operator: ''}] - ); - pandora.URL.update(); + pandora.UI.set({listSort: [{key: value, operator: ''}]}); } else if (data.id == 'viewicons') { - var $list; pandora.UI.set({icons: value}); - if (pandora.user.ui.item) { - if (pandora.user.ui.itemView == 'info') { - pandora.$ui.item.reload(); - } - $list = pandora.$ui.browser; - } else if (pandora.user.ui.lists[pandora.user.ui.list].listView == 'grid') { - $list = pandora.$ui.list; - } - $list && $list.options({ - borderRadius: value == 'posters' ? 0 : pandora.user.ui.item ? 8 : 16, - defaultRatio: value == 'posters' ? 5/8 : 1 - }).reloadList(true); } else if (data.id == 'viewmovies') { - pandora.UI.set('lists|' + pandora.user.ui.list + '|listView', value); - pandora.URL.update(); + pandora.UI.set('listView', value); } else if (['personallists', 'favoritelists', 'featuredlists'].indexOf(value) > -1) { - pandora.URL.set( - data.checked[0] ? '?find=list:' + value.substr(8) : '' - ); + pandora.UI.set({list: value.substr(8)}); } }, click: function(data) { - if (data.id == 'home') { - pandora.$ui.home = pandora.ui.home().fadeInScreen(); - pandora.URL.push('home'); - } else if (['about', 'news', 'tour', 'faq', 'tos', 'contact', 'software'].indexOf(data.id) > -1) { - pandora.$ui.siteDialog = pandora.ui.siteDialog(data.id).open(); - pandora.URL.push(data.id); - } else if (data.id == 'preferences') { - pandora.$ui.preferencesDialog = pandora.ui.preferencesDialog().open(); - } else if (data.id == 'signup') { - pandora.$ui.accountDialog = pandora.ui.accountDialog('signup').open(); - } else if (data.id == 'signinsignout') { - pandora.$ui.accountDialog = ( - pandora.user.level == 'guest' - ? pandora.ui.accountDialog('signin') - : pandora.ui.accountSignoutDialog() - ).open(); + if ([ + 'home', 'about', 'news', 'tour', 'faq', 'tos', 'contact', 'software', + 'signup', 'signin', 'signout', 'preferences', 'help' + ].indexOf(data.id) > -1) { + pandora.URL.push('/' + data.id); } else if (data.id == 'stills') { var id = pandora.user.ui.item || pandora.user.ui.listItem; pandora.$ui.postersDialog = pandora.ui.framesDialog(id).open(); diff --git a/static/js/pandora/ui/orderButton.js b/static/js/pandora/ui/orderButton.js new file mode 100644 index 00000000..f481da91 --- /dev/null +++ b/static/js/pandora/ui/orderButton.js @@ -0,0 +1,34 @@ +// vim: et:ts=4:sw=4:sts=4:ft=javascript + +pandora.ui.orderButton = function() { + var that = Ox.Button({ + id: 'orderButton', + title: getTitle(), + // tooltip: 'Change sort order', + type: 'image' + }) + .css({ + float: 'left', + margin: '4px 0 0 4px' + }) + .bindEvent({ + click: function(data) { + pandora.UI.set({ + listSort: [{ + key: pandora.user.ui.listSort[0].key, + operator: pandora.user.ui.listSort[0].operator == '+' ? '-' : '+' + }] + }) + that.options({title: getTitle()}); + } + }); + function getTitle() { + return pandora.user.ui.listSort[0].operator == '+' ? 'up' : 'down'; + } + Ox.Event.bind({ + listSort: function() { + that.options({title: getTitle()}); + } + }); + return that; +} \ No newline at end of file diff --git a/static/js/pandora/ui/rightPanel.js b/static/js/pandora/ui/rightPanel.js index 3374def8..abd72976 100644 --- a/static/js/pandora/ui/rightPanel.js +++ b/static/js/pandora/ui/rightPanel.js @@ -40,24 +40,30 @@ pandora.ui.rightPanel = function() { pandora.resizeGroups(); pandora.$ui.list.size(); if (pandora.user.ui.lists[pandora.user.ui.list].listView == 'timelines') { - pandora.$ui.list.options({ - width: data.size - }); + pandora.$ui.list.options({width: data.size}); } else if (pandora.user.ui.lists[pandora.user.ui.list].listView == 'map') { pandora.$ui.map.resizeMap(); + } else if (pandora.user.ui.lists[pandora.user.ui.list].listView == 'calendar') { + } } else { pandora.$ui.browser.scrollToSelection(); - pandora.user.ui.itemView == 'player' && pandora.$ui.player.options({ - width: data.size - }); - pandora.user.ui.itemView == 'timeline' && pandora.$ui.editor.options({ - width: data.size - }); + if (pandora.user.ui.itemView == 'video') { + pandora.$ui.player.options({width: data.size}); + } else if (pandora.user.ui.itemView == 'timeline') { + pandora.$ui.editor.options({width: data.size}); + } } } }); } + Ox.Event.bind({ + itemView: function(value) { + if (pandora.isClipView() != pandora.isClipView(pandora.UI.getPrevious('itemView'))) { + that.replaceElement(0, pandora.$ui.toolbar = pandora.ui.toolbar()); + } + } + }) return that; }; diff --git a/static/js/pandora/ui/siteDialog.js b/static/js/pandora/ui/siteDialog.js index 22d59ef3..8bed030c 100644 --- a/static/js/pandora/ui/siteDialog.js +++ b/static/js/pandora/ui/siteDialog.js @@ -52,7 +52,7 @@ pandora.ui.siteDialog = function(section) { }).bindEvent({ click: function() { $dialog.close(); - pandora.URL.pushPrevious(); + pandora.URL.push(); } }) ], diff --git a/static/js/pandora/ui/sortSelect.js b/static/js/pandora/ui/sortSelect.js index e84e280c..08b88074 100644 --- a/static/js/pandora/ui/sortSelect.js +++ b/static/js/pandora/ui/sortSelect.js @@ -1,20 +1,24 @@ // vim: et:ts=4:sw=4:sts=4:ft=javascript pandora.ui.sortSelect = function() { - var list = pandora.user.ui.lists[pandora.user.ui.list], - items = pandora.site.sortKeys.map(function(key) { - return Ox.extend(Ox.clone(key), { - checked: list.sort[0].key == key.id, - title: 'Sort by ' + key.title - }); - }), + var items = [], + sortKey = !pandora.user.ui.item ? 'listSort' : 'itemSort', that; - if (pandora.isClipView(list.listView)) { - items = Ox.merge(pandora.site.clipKeys.map(function(key) { + if (pandora.isClipView()) { + items = pandora.site.clipKeys.map(function(key) { return Ox.extend(Ox.clone(key), { - checked: list.sort[0].key == key.id, + checked: key.id == pandora.user.ui[sortKey][0].key, + title: 'Sort by ' + (!pandora.user.ui.item ? 'Clip ' : '') + key.title + }); + }); + !pandora.user.ui.item && items.push({}); + } + if (!pandora.user.ui.item) { + items = Ox.merge(items, pandora.site.sortKeys.map(function(key) { + return Ox.extend(Ox.clone(key), { + checked: key.id == pandora.user.ui[sortKey][0].key, title: 'Sort by ' + key.title }); - }), {}, items); + })); } that = Ox.Select({ id: 'sortSelect', @@ -27,14 +31,18 @@ pandora.ui.sortSelect = function() { }) .bindEvent({ change: function(data) { - //var query = Ox.unserialize(document.location.search); - //query.sort = data.selected.id; - //pandora.URL.set('/' + pandora.user.ui.lists[pandora.user.ui.list].listView + '/?' + Ox.serialize(query)); - pandora.UI.set( - 'lists|' + pandora.user.ui.list + '|sort', - [{key: data.selected[0].id, operator: ''}] - ); - pandora.URL.update(); + pandora.UI.set(sortKey, [{key: data.selected[0].id, operator: ''}]); + } + }); + Ox.Event.bind({ + listSort: function(value) { + that.selectItem(value[0].key); + }, + item: function(valye) { + + }, + itemSort: function(value) { + that.selectItem(value[0].key); } }); return that; diff --git a/static/js/pandora/ui/toolbar.js b/static/js/pandora/ui/toolbar.js index 5d248a42..a0b55266 100644 --- a/static/js/pandora/ui/toolbar.js +++ b/static/js/pandora/ui/toolbar.js @@ -12,15 +12,19 @@ pandora.ui.toolbar = function() { that.append( pandora.$ui.viewSelect = pandora.ui.viewSelect() ); - !pandora.user.ui.item && that.append( - pandora.$ui.sortSelect = pandora.ui.sortSelect() - ); + if (!pandora.user.ui.item || pandora.isClipView()) { + that.append( + pandora.$ui.sortSelect = pandora.ui.sortSelect() + ); + } + if (!pandora.user.ui.item) { + that.append( + pandora.$ui.orderButton = pandora.ui.orderButton() + ); + } that.append( pandora.$ui.findElement = pandora.ui.findElement() ); - that.display = function() { - pandora.$ui.rightPanel.replaceElement(0, pandora.$ui.toolbar = pandora.ui.toolbar()); // fixme: remove later - } return that; }; diff --git a/static/js/pandora/ui/videoPreview.js b/static/js/pandora/ui/videoPreview.js index 5b1ee027..b5b885fa 100644 --- a/static/js/pandora/ui/videoPreview.js +++ b/static/js/pandora/ui/videoPreview.js @@ -20,9 +20,9 @@ pandora.ui.videoPreview = function(data) { }) .bindEvent({ click: function(event) { - if (pandora.user.ui.item) { + if (pandora.user.ui.item && ['video', 'timeline'].indexOf(pandora.user.ui.itemView) > -1) { pandora.$ui[ - pandora.user.ui.itemView == 'player' ? 'player' : 'editor' + pandora.user.ui.itemView == 'video' ? 'player' : 'editor' ].options({ position: event.position }); @@ -31,8 +31,8 @@ pandora.ui.videoPreview = function(data) { 'videoPoints|' + data.id, {'in': 0, out: 0, position: event.position} ); - pandora.URL.set( - '/' + data.id + '/timeline' //'/' + Ox.formatDuration(event.position, 2) + pandora.URL.push( + '/' + data.id + '/' + pandora.user.ui.videoView + '/' + Ox.formatDuration(event.position, 2) ); } } diff --git a/static/js/pandora/ui/viewSelect.js b/static/js/pandora/ui/viewSelect.js index ab420c7b..d9235789 100644 --- a/static/js/pandora/ui/viewSelect.js +++ b/static/js/pandora/ui/viewSelect.js @@ -1,17 +1,14 @@ // vim: et:ts=4:sw=4:sts=4:ft=javascript + pandora.ui.viewSelect = function() { - var that = Ox.Select({ + var viewKey = !pandora.user.ui.item ? 'listView' : 'itemView', + that = Ox.Select({ id: 'viewSelect', - items: !pandora.user.ui.item ? pandora.site.listViews.map(function(view) { - return Ox.extend(Ox.extend({}, view), { - checked: pandora.user.ui.lists[pandora.user.ui.list].listView == view.id, + items: pandora.site[viewKey + 's'].map(function(view) { + return Ox.extend(Ox.clone(view), { + checked: view.id == pandora.user.ui[viewKey], title: 'View ' + view.title }); - }) : pandora.site.itemViews.map(function(view) { - return Ox.extend(Ox.extend({}, view), { - checked: pandora.user.ui.itemView == view.id, - title: 'View: ' + view.title - }); }), width: !pandora.user.ui.item ? 144 : 128 }) @@ -20,16 +17,18 @@ pandora.ui.viewSelect = function() { margin: '4px 0 0 4px' }) .bindEvent({ - change: !pandora.user.ui.item ? function(data) { - pandora.UI.set('lists|' + pandora.user.ui.list + '|listView', data.selected[0].id); - pandora.URL.update(); - //pandora.URL.set('/' + data.selected[0].id + '/' + document.location.search); - } : function(data) { - pandora.UI.set({itemView: data.selected[0].id}); - pandora.URL.update(); - // pandora.$ui.contentPanel.replaceElement(1, pandora.$ui.item = pandora.ui.item()); + change: function(data) { + pandora.UI.set(viewKey, data.selected[0].id); } }); + Ox.Event.bind({ + listView: function(value) { + that.selectItem(value); + }, + itemView: function(value) { + that.selectItem(value); + } + }); return that; }; diff --git a/static/json/pandora.json b/static/json/pandora.json index 3216b778..5ae27da9 100644 --- a/static/json/pandora.json +++ b/static/json/pandora.json @@ -20,10 +20,11 @@ "js/pandora/ui/sectionbar.js", "js/pandora/ui/folders.js", "js/pandora/ui/mainPanel.js", + "js/pandora/ui/viewSelect.js", "js/pandora/ui/sortSelect.js", + "js/pandora/ui/orderButton.js", "js/pandora/ui/menu.js", "js/pandora/ui/Ox.FilesView.js", - "js/pandora/ui/viewSelect.js", "js/pandora/ui/browser.js", "js/pandora/ui/list.js", "js/pandora/ui/foldersList.js",