From d4141a1e0093c2c52dbb3940d2b851a5c430b864 Mon Sep 17 00:00:00 2001 From: rolux Date: Thu, 13 Jan 2011 19:40:50 +0000 Subject: [PATCH] even more improvements to lists --- pandora/item/managers.py | 11 +- pandora/item/utils.py | 13 + pandora/item/views.py | 12 +- pandora/itemlist/models.py | 1 + pandora/itemlist/views.py | 104 ++- static/js/pandora.api.js | 4 +- static/js/pandora.js | 1757 ++---------------------------------- 7 files changed, 154 insertions(+), 1748 deletions(-) diff --git a/pandora/item/managers.py b/pandora/item/managers.py index c641c832..7fb32b8f 100644 --- a/pandora/item/managers.py +++ b/pandora/item/managers.py @@ -87,12 +87,13 @@ def parseCondition(condition): if len(l) == 2: lqs = List.objects.filter(name=l[1], user__username=l[0]) if lqs.count() == 1: - if lqs[0].query.get('static', False) == False: - data = lqs[0].query - q = parseConditions(data['conditions'], + l = lqs[0] + if l.query.get('static', False) == False: + data = l.query + q = parseConditions(data.get('conditions', []), data.get('operator', '&')) else: - q = Q(id__in=lqs[0].items.all()) + q = Q(id__in=l.items.all()) return q else: #number or date @@ -237,7 +238,7 @@ class ItemManager(Manager): qs = self.get_query_set() #only include items that have hard metadata qs = qs.filter(available=True) - conditions = parseConditions(data['query']['conditions'], + conditions = parseConditions(data['query'].get('conditions', []), data['query'].get('operator', '&')) if conditions: qs = qs.filter(conditions) diff --git a/pandora/item/utils.py b/pandora/item/utils.py index 9812bbaa..90ffda7c 100644 --- a/pandora/item/utils.py +++ b/pandora/item/utils.py @@ -206,3 +206,16 @@ def sort_title(title): #pad numbered titles title = re.sub('(\d+)', lambda x: '%010d' % int(x.group(0)), title) return title.strip() + +def get_positions(ids, pos): + ''' + >>> get_positions([1,2,3,4], [2,4]) + {2: 1, 4: 3} + ''' + positions = {} + for i in pos: + try: + positions[i] = ids.index(i) + except: + pass + return positions diff --git a/pandora/item/views.py b/pandora/item/views.py index 24cbdcf4..7643adb2 100644 --- a/pandora/item/views.py +++ b/pandora/item/views.py @@ -70,16 +70,6 @@ def _parse_query(data, user): return query -def _get_positions(ids, get_ids): - positions = {} - for i in get_ids: - try: - positions[i] = ids.index(i) - except: - pass - return positions - - def find(request): ''' param data { @@ -184,7 +174,7 @@ Positions #FIXME: this does not scale for larger results response['data']['positions'] = {} ids = [j['value'] for j in qs] - response['data']['positions'] = _get_positions(ids, query['ids']) + response['data']['positions'] = utils.get_positions(ids, query['ids']) elif 'range' in data: qs = qs[query['range'][0]:query['range'][1]] diff --git a/pandora/itemlist/models.py b/pandora/itemlist/models.py index 083f899d..a3b7b2c9 100644 --- a/pandora/itemlist/models.py +++ b/pandora/itemlist/models.py @@ -25,6 +25,7 @@ class List(models.Model): query = DictField(default={"static": True}) type= models.CharField(max_length=255, default='static') + #is through table still required? items = models.ManyToManyField('item.Item', related_name='lists', through='ListItem') diff --git a/pandora/itemlist/views.py b/pandora/itemlist/views.py index b17e70c4..293dc4ca 100644 --- a/pandora/itemlist/views.py +++ b/pandora/itemlist/views.py @@ -2,12 +2,14 @@ # vi:si:et:sw=4:sts=4:ts=4 from __future__ import division +from django.db.models import Max from ox.utils import json from ox.django.decorators import login_required_json from ox.django.shortcuts import render_to_json_response, get_object_or_404_json, json_response import models from api.actions import actions +from item import utils def get_list_or_404_json(id): @@ -31,17 +33,15 @@ def _parse_query(data, user): query = {} query['range'] = [0, 100] query['sort'] = [{'key':'user', 'operator':'+'}, {'key':'name', 'operator':'+'}] - #query['sort'] = [{'key':'position__position', 'operator':'+'}] - query['sort'] = [{'key':'name', 'operator':'+'}] for key in ('keys', 'group', 'list', 'range', 'ids', 'sort'): if key in data: query[key] = data[key] query['qs'] = models.List.objects.find(data, user) return query + def findLists(request): ''' - FIXME: support key: subscribed param data { query: { conditions: [ @@ -78,12 +78,17 @@ def findLists(request): #order is_section_request = query['sort'] == [{u'operator': u'+', u'key': u'position'}] - is_featured = len(filter(lambda x: x['key'] == 'status' and x['value'] == 'featured' and x['operator'] == '=', data['query'].get('conditions', []))) > 0 + def is_featured_condition(x): + return x['key'] == 'status' and \ + x['value'] == 'featured' and \ + x['operator'] == '=' + is_featured = len(filter(is_featured_condition, data['query'].get('conditions', []))) > 0 if is_section_request: qs = query['qs'] if not is_featured: - qs = qs.filter(position__in=models.Position.objects.filter(user=request.user)) + if not request.user.is_anonymous(): + qs = qs.filter(position__in=models.Position.objects.filter(user=request.user)) qs = qs.order_by('position__position') else: qs = _order_query(query['qs'], query['sort']) @@ -94,6 +99,9 @@ def findLists(request): qs = qs[query['range'][0]:query['range'][1]] response['data']['items'] = [l.json(data['keys'], request.user) for l in qs] + elif 'ids' in data: + ids = [i.get_id() for i in qs] + response['data']['positions'] = utils.get_positions(ids, query['ids']) else: response['data']['items'] = qs.count() return render_to_json_response(response) @@ -105,7 +113,7 @@ def addListItem(request): param data {list: listId, item: itemId, - quert: ... + query: ... } return { status: {'code': int, 'text': string}, @@ -124,7 +132,6 @@ def addListItem(request): response = json_response(status=403, text='not allowed') elif 'query' in data: response = json_response(status=501, text='not implemented') - else: response = json_response(status=501, text='not implemented') return render_to_json_response(response) @@ -168,7 +175,6 @@ def addList(request): ''' param data { name: value, - position: int } return { status: {'code': int, 'text': string}, @@ -185,9 +191,31 @@ def addList(request): name = data['name'] + ' (%d)' % num list = models.List(name = name, user=request.user) list.save() + for key in data: + if key == 'query' and not data['query']: + setattr(list, key, {"static":True}) + elif key == 'query': + setattr(list, key, data[key]) + elif key == 'type': + if data[key] == 'static': + list.query = {"static":True} + list.type = 'static' + else: + list.type = 'dynamic' + if list.query.get('static', False): + list.query = {} + elif key == 'status': + value = data[key] + if value not in list._status: + value = list._status[0] + setattr(list, key, value) + + list.save() + pos, created = models.Position.objects.get_or_create(list=list, user=request.user, section='my') - pos.position = data['position'] + qs = models.Position.objects.filter(user=request.user, section='my') + pos.position = qs.aggregate(Max('position'))['position__max'] + 1 pos.save() response = json_response(status=200, text='created') response['data'] = list.json() @@ -216,35 +244,35 @@ def editList(request): if list.editable(request.user): response = json_response() for key in data: - if key in ('name', 'status', 'query', 'type'): - if key in data: - if key == 'query' and not data['query']: - setattr(list, key, {"static":True}) - elif key == 'type': - if data[key] == 'static': - list.query = {"static":True} - list.type = 'static' - else: - list.type = 'dynamic' - if list.query.get('static', False): - list.query = {} - elif key == 'status': - value = data[key] - if value not in list._status: - value = list._status[0] - setattr(list, key, value) - if value == 'private': - for user in list.subscribed_users.all(): - list.subscribed_users.remove(user) - elif key == 'name': - name = data['name'] - num = 1 - while models.List.objects.filter(name=name, user=list.user).exclude(id=list.id).count()>0: - num += 1 - name = data['name'] + ' (%d)' % num - setattr(list, key, name) - else: - setattr(list, key, data[key]) + if key == 'query' and not data['query']: + setattr(list, key, {"static":True}) + elif key == 'query': + setattr(list, key, data[key]) + elif key == 'type': + if data[key] == 'static': + list.query = {"static":True} + list.type = 'static' + else: + list.type = 'dynamic' + if list.query.get('static', False): + list.query = {} + elif key == 'status': + value = data[key] + if value not in list._status: + value = list._status[0] + setattr(list, key, value) + if value == 'private': + for user in list.subscribed_users.all(): + list.subscribed_users.remove(user) + elif key == 'name': + name = data['name'].strip() + if not name: + name = "Untitled" + num = 1 + while models.List.objects.filter(name=name, user=list.user).exclude(id=list.id).count()>0: + num += 1 + name = data['name'] + ' (%d)' % num + setattr(list, key, name) if 'position' in data: pos, created = models.Position.objects.get_or_create(list=list, user=request.user) diff --git a/static/js/pandora.api.js b/static/js/pandora.api.js index eb5a429f..3e72b325 100755 --- a/static/js/pandora.api.js +++ b/static/js/pandora.api.js @@ -68,14 +68,14 @@ function constructList() { if(!data.keys) { app.api.api(function(results) { var items = []; - $.each(results.data.actions, function(i, k) {items.push({'name': k})}); + $.each(results.data.actions, function(i, k) {items.push({'name': i})}); var result = {'data': {'items': items.length}}; callback(result); }); } else { app.api.api(function(results) { var items = []; - $.each(results.data.actions, function(i, k) {items.push({'name': k})}); + $.each(results.data.actions, function(i, k) {items.push({'name': i})}); var result = {'data': {'items': items}}; callback(result); }); diff --git a/static/js/pandora.js b/static/js/pandora.js index 899501a3..0bfa4c0e 100755 --- a/static/js/pandora.js +++ b/static/js/pandora.js @@ -1095,6 +1095,7 @@ var pandora = new Ox.App({ app.$ui.sectionbar.append(app.$ui.sectionButtons = ui.sectionButtons()); } ///* + Ox.print('data', data); app.$ui.leftPanel.find('.OxTextList').css({ width: data + 'px' }); @@ -1105,8 +1106,9 @@ var pandora = new Ox.App({ width: data + 'px' }); app.$ui.leftPanel.find('.OxCell.OxColumnName').css({ - width: (data - 88) + 'px' + width: (data - 96) + 'px' }); + Ox.print(app.$ui.leftPanel.find('.OxCell.OxColumnName').css('width')) //*/ //Ox.print('resize', data, data / app.ui.infoRatio + 16); app.$ui.leftPanel.size('infoPanel', Math.round(data / app.ui.infoRatio) + 16); @@ -1288,7 +1290,7 @@ var pandora = new Ox.App({ app.$ui.previewDialog.close(); delete app.$ui.previewDialog; }, - load: function(event, data) { + init: function(event, data) { app.$ui.total.html(ui.status('total', data)); data = []; $.each(app.config.totals, function(i, v) { @@ -2110,7 +2112,7 @@ var pandora = new Ox.App({ var $sections = []; app.$ui.sectionLists = []; $.each(app.user.ui.sections, function(i, id) { - var menu = []; + var $section, menu = []; if (id == 'my') { menu = [ { id: 'new', title: 'New List...' }, @@ -2125,12 +2127,37 @@ var pandora = new Ox.App({ { id: 'browse', title: 'More Public Lists...' }, ]; } - var $section = new Ox.CollapsePanel({ - id: id, - menu: menu, - size: 16, - title: Ox.getObjectById(app.config.sections, id).title - }); + $section = new Ox.CollapsePanel({ + id: id, + menu: menu, + size: 16, + title: Ox.getObjectById(app.config.sections, id).title + }) + .bindEvent({ + click: function(event, data) { + var $list = app.$ui.sectionLists[i], + id; + if (data.id == 'new' || data.id == 'newsmart') { + pandora.api.addList({ + name: 'Untitled', + status: 'private', + type: data.id == 'new' ? 'static' : 'smart' + }, function(result) { + id = result.data.id; + Ox.Request.emptyCache(); // fixme: remove + $list.reloadList() + .bindEvent({load: load}); + }); + } + function load(event, data) { + $list.gainFocus() + .options({selected: [id]}) + .editCell(id, 'name'); + Ox.print('load', id, $list.options('selected')) + $list.unbindEvent({load: load}) // fixme: need bindEventOnce + } + } + }); $sections.push($section); app.$ui.sectionLists[i] = new Ox.TextList({ columns: [ @@ -2255,7 +2282,7 @@ var pandora = new Ox.App({ }) .bindEvent({ click: function(event, data) { - var list = app.$ui.sectionLists[i]; + var $list = app.$ui.sectionLists[i]; if (data.key == 'type') { var $dialog = new Ox.Dialog({ buttons: [ @@ -2281,13 +2308,24 @@ var pandora = new Ox.App({ } else if (data.key == 'status') { pandora.api.editList({ id: data.id, - status: list.value(data.id, data.key) == 'private' ? 'public' : 'private' + status: $list.value(data.id, data.key) == 'private' ? 'public' : 'private' }, function(result) { - list.value(result.data.id, 'status', result.data.status); + $list.value(result.data.id, 'status', result.data.status); }); } }, - load: function(event, data) { + 'delete': function(event, data) { + var $list = app.$ui.sectionLists[i]; + URL.set(''); + $list.options({selected: []}); + pandora.api.removeList({ + id: data.ids[0] + }, function() { + Ox.Request.emptyCache(); // fixme: remove + $list.reloadList(); + }); + }, + init: function(event, data) { $section.$content.css({ height: data.items * 16 + 'px' }); @@ -2307,17 +2345,24 @@ var pandora = new Ox.App({ }); }, select: function(event, data) { - app.$ui.sectionLists.forEach(function($list, i_) { - i != i_ && $list.options('selected', []); - }); - URL.set('?find=list:' + data.ids[0]); + if (data.ids.length) { + app.$ui.sectionLists.forEach(function($list, i_) { + i != i_ && $list.options('selected', []); + }); + URL.set('?find=list:' + data.ids[0]); + } else { + URL.set(''); + } }, submit: function(event, data) { data_ = {id: data.id}; data_[data.key] = data.value; pandora.api.editList(data_, function(result) { - app.$ui.sectionLists[i].value(data.id, 'name', result.data.name); - app.$ui.sectionLists[i].value(data.id, 'id', result.data.id); + if (result.data.name != data_.name) { + app.$ui.sectionLists[i].value(data.id, 'name', result.data.name); + app.$ui.sectionLists[i].value(data.id, 'id', result.data.id); + URL.set('?find=list:' + result.data.id); + } }); } }) @@ -2879,1676 +2924,4 @@ var pandora = new Ox.App({ load(); -}); - - - -// Objects - -/* - // Menu - - - Ox.Event.bind('change_viewmovies', function(event, data) { - app.$ui.viewSelect.selectItem(data.id); - }); - Ox.Event.bind('change_find', function(event, data) { - app.$ui.findInput.changeLabel(data.id); - }); - Ox.Event.bind('click_query', function(event, data) { - var $dialog = new Ox.Dialog({ - buttons: [ - { - click: function() { - $dialog.close(); - }, - id: 'close', - title: 'Close', - value: 'Close' - } - ], - id: 'query', - title: 'Query' - }).append(Query.toString() + '

' + JSON.stringify(Query.toObject())).open(); - }); - - // Resize - - Ox.Event.bind('click_show_query', function(event, data) { - var query = constructQuery(), - html = 'Conditions

' + $.map(query.conditions, function(v) { - return v.key + ' ' + v.operator + ' ' + v.value; - }).join('
') + '

Operator: ' + query.operator, - $dialog = new Ox.Dialog({ - buttons: [ - { - value: 'Close', - click: function() { - $dialog.close(); - } - } - ], - title: 'Show Query' - }) - .append(html) - .open(); - }); - -// Functions -*/ - -/* - -app.constructAnnotations = function() { - var $annotations = new Ox.Element(); - $.each(app.constructBins(), function(i, $bin) { - $annotations.append($bin); - }); - return $annotations; -} - -app.constructApp = function() { - return new Ox.SplitPanel({ - elements: [ - { - element: app.$ui.mainMenu, - size: 20 - }, - { - element: app.$ui.mainPanel = new Ox.SplitPanel({ - elements: [ - { - collapsible: true, - element: app.$ui.leftPanel = new Ox.SplitPanel({ - elements: [ - { - element: app.$ui.sectionbar, - size: 24 - }, - { - element: app.$ui.lists.options({ - id: 'listsPanel' - }) - }, - { - collapsible: true, - element: app.$ui.info.options({ - id: 'infoPanel' - }), - size: app.user.ui.listsSize / app.ui.infoRatio + 16 - } - ], - id: 'leftPanel', - orientation: 'vertical' - }) - .bindEvent('resize', function(event, data) { - Ox.print('resize', data, data / app.ui.infoRatio + 16); - app.$ui.leftPanel.size('infoPanel', Math.round(data / app.ui.infoRatio) + 16); - }), - resizable: true, - resize: [128, 256, 384, 512], - size: app.user.ui.listsSize - }, - { - element: app.$ui.rightPanel = new Ox.SplitPanel({ - elements: [ - { - element: app.$ui.toolbar.css({ zIndex: 2 }), // fixme: remove later - size: 24 - }, - { - element: app.constructContentPanel() - }, - { - element: app.$ui.statusbar, - size: 16 - } - ], - id: 'rightPanel', - orientation: 'vertical' - }) - .bindEvent('resize', function(event, data) { - var widths = $.map(app.ui.groups, function(v, i) { - return app.getGroupWidth(i, data); - }); - Ox.print('widths', widths); - app.$ui.groupsOuterPanel.size(0, widths[0].list).size(2, widths[4].list); - app.$ui.groupsInnerPanel.size(0, widths[1].list).size(2, widths[3].list); - $.each(app.$ui.groups, function(i, list) { - list.resizeColumn('name', widths[i].column); - }); - app.$ui.list.size(); - }) - } - ], - orientation: 'horizontal' - }) - } - ], - orientation: 'vertical' - }); -} - -app.constructBins = function() { - var $bins = []; - $.each(app.config.layers, function(i, layer) { - var $bin = new Ox.CollapsePanel({ - id: layer.id, - size: 16, - title: layer.title - }); - $bins.push($bin); - $bin.$content.append( - $('
').css({ height: '20px' }).append( - $('
').css({ float: 'left', width: '16px', height: '16px', margin: '1px'}).append( - $('').attr({ src: 'static/oxjs/build/png/ox.ui.modern/iconFind.png' }).css({ width: '16px', height: '16px', border: 0, background: 'rgb(64, 64, 64)', WebkitBorderRadius: '2px' }) - ) - ).append( - $('
').css({ float: 'left', width: '122px', height: '14px', margin: '2px' }).html('Foo') - ).append( - $('
').css({ float: 'left', width: '40px', height: '14px', margin: '2px', textAlign: 'right' }).html('23') - ) - ); - }); - return $bins; -} - -app.constructGroups = function() { - var $groups = [], - panelWidth = app.$document.width() - app.user.ui.listsSize - 1; - app.ui.groups = $.map(app.config.groups, function(id, i) { - var title = Ox.getObjectById(app.config.sortKeys, id).title, - width = app.getGroupWidth(i, panelWidth); - return { - id: id, - element: $groups[i] = new Ox.TextList({ - columns: [ - { - align: 'left', - id: 'name', - operator: id == 'year' ? '-' : '+', - title: title, - unique: true, - visible: true, - width: width.column - }, - { - align: 'right', - id: 'items', - operator: '-', - title: '#', - visible: true, - width: 40 - } - ], - id: 'group_' + id, - request: function(data, callback) { - Ox.print('sending request', data) - delete data.keys; - return pandora.api.find($.extend(data, { - group: id, - query: app.Query.toObject() - }), callback); - }, - sort: [ - { - key: id == 'year' ? 'name' : 'items', - operator: '-' - } - ] - }) - .bindEvent('select', function(event, data) { - Ox.print('select', i) - var group = app.ui.groups[i], - query; - app.ui.groups[i].query.conditions = $.map(data.ids, function(v) { - return { - key: group.id, - value: v, - operator: '=' - }; - }); - query = app.Query.toObject(); - app.$ui.list.options({ - request: function(data, callback) { - return pandora.api.find($.extend(data, { - query: query - }), callback); - } - }); - $.each(app.ui.groups, function(i_, group_) { - if (i_ != i) { - Ox.print('setting groups request', i, i_) - app.$ui.groups[i_].options({ - request: function(data, callback) { - delete data.keys; - return pandora.api.find($.extend(data, { - group: group_.id, - query: app.Query.toObject(group_.id) - }), callback); - } - }); - } - }); - history.pushState({}, '', '/#' + app.Query.toString(query)); - }), - query: { - conditions: [], - operator: '|' - }, - size: width.list, - title: title - }; - Ox.print('--OK--'); - }); - return $groups; -} - -app.constructInfo = function() { - return new Ox.Element() - .append( - app.$ui.infoStill = new Ox.Element('img') - .css({ - position: 'absolute', - left: 0, - top: 0 - }) - ) - .append( - app.$ui.infoTimeline = new Ox.Element('img') - .css({ - position: 'absolute', - left: 0, - bottom: 0, - height: '16px', - }) - ); -} - -app.constructContentPanel = function(listView) { - listView = listView || app.user.ui.listView; - return app.$ui.contentPanel = new Ox.SplitPanel({ - elements: [ - { - collapsible: true, - element: app.$ui.groupsOuterPanel = new Ox.SplitPanel({ - elements: [ - { - element: app.$ui.groups[0], - size: app.ui.groups[0].size - }, - { - element: app.$ui.groupsInnerPanel = new Ox.SplitPanel({ - elements: [ - { - element: app.$ui.groups[1], - size: app.ui.groups[1].size - }, - { - element: app.$ui.groups[2], - }, - { - element: app.$ui.groups[3], - size: app.ui.groups[3].size - } - ], - orientation: 'horizontal' - }) - }, - { - element: app.$ui.groups[4], - size: app.ui.groups[4].size - }, - ], - id: 'browser', - orientation: 'horizontal' - }) - .bindEvent('resize', function(event, data) { - Ox.print('resizing groups...') - $.each(app.$ui.groups, function(i, list) { - list.size(); - }); - }), - resizable: true, - resize: [96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256], - size: app.user.ui.groupsSize - }, - { - element: app.$ui.list = app.constructList(listView) - } - ], - orientation: 'vertical' - }); -} - -app.constructItem = function(id, view) { - -} - -app.constructList = function(view) { - - -} - -app.constructLists = function() { - var $lists = new Ox.Element; - $.each(app.$ui.sections, function(i, $section) { - $lists.append($section); - }); - return $lists; -} - -app.constructMainMenu = function() { - return new Ox.MainMenu({ - extras: [ - app.$ui.loadingIcon = new Ox.LoadingIcon({ - size: 'medium' - }) - ], - id: 'mainMenu', - menus: [ - { id: app.config.site.id + 'Menu', title: app.config.site.name, items: [ - { id: 'about', title: 'About' }, - {}, - { id: 'home', title: 'Home Screen' }, - { id: 'faq', title: 'Frequently Asked Questions' }, - { id: 'tos', title: 'Terms of Service' }, - {}, - { id: 'contact', title: 'Contact...' } - ] }, - { id: 'userMenu', title: 'User', items: [ - { id: 'username', title: 'User: not logged in', disabled: true }, - {}, - { id: 'preferences', title: 'Preferences...', disabled: true, keyboard: 'control ,' }, - {}, - { id: 'register', title: 'Create an Account...' }, - { id: 'loginlogout', title: ['Login...', 'Logout...'] } - ] }, - { id: 'listMenu', title: 'List', items: [ - { id: 'history', title: 'History', items: [ - { id: 'allmovies', title: 'All Movies' } - ] }, - { id: 'lists', title: 'View List', items: [ - { id: 'favorites', title: 'Favorites' } - ] }, - { id: 'features', title: 'View Feature', items: [ - { id: 'situationistfilm', title: 'Situationist Film' }, - { id: 'timelines', title: 'Timelines' } - ] }, - {}, - { id: 'newlist', title: 'New List...', keyboard: 'control n' }, - { id: 'newlistfromselection', title: 'New List from Selection...', disabled: true, keyboard: 'shift control n' }, - { id: 'newsmartlist', title: 'New Smart List...', keyboard: 'alt control n' }, - { id: 'newsmartlistfromresults', title: 'New Smart List from Results...', keyboard: 'shift alt control n' }, - {}, - { id: 'addmovietolist', title: ['Add Selected Movie to List...', 'Add Selected Movies to List...'], disabled: true }, - {}, - { id: 'setposterframe', title: 'Set Poster Frame', disabled: true } - ]}, - { id: 'editMenu', title: 'Edit', items: [ - { id: 'undo', title: 'Undo', disabled: true, keyboard: 'control z' }, - { id: 'redo', title: 'Redo', disabled: true, keyboard: 'shift control z' }, - {}, - { id: 'cut', title: 'Cut', disabled: true, keyboard: 'control x' }, - { id: 'copy', title: 'Copy', disabled: true, keyboard: 'control c' }, - { id: 'paste', title: 'Paste', disabled: true, keyboard: 'control v' }, - { id: 'delete', title: 'Delete', disabled: true, keyboard: 'delete' }, - {}, - { id: 'selectall', title: 'Select All', disabled: true, keyboard: 'control a' }, - { id: 'selectnone', title: 'Select None', disabled: true, keyboard: 'shift control a' }, - { id: 'invertselection', title: 'Invert Selection', disabled: true, keyboard: 'alt control a' } - ] }, - { id: 'viewMenu', title: 'View', items: [ - { id: 'movies', title: 'View Movies', items: [ - { group: 'viewmovies', min: 0, max: 1, items: $.map(app.config.listViews, function(view, i) { - return $.extend({ - checked: app.user.ui.listView == view.id, - }, view); - }) }, - ]}, - { id: 'icons', title: 'Icons', items: [ - { id: 'poster', title: 'Poster' }, - { id: 'still', title: 'Still' }, - { id: 'timeline', title: 'Timeline' } - ] }, - { id: 'info', title: 'Info', items: [ - { id: 'poster', title: 'Poster' }, - { id: 'video', title: 'Video' } - ] }, - {}, - { id: 'openmovie', title: ['Open Movie', 'Open Movies'], disabled: true, items: [ - { group: 'movieview', min: 0, max: 1, items: $.map(app.config.itemViews, function(view, i) { - return $.extend({ - checked: app.user.ui.itemView == view.id, - }, view); - }) }, - ]}, - {}, - { id: 'lists', title: 'Hide Lists', keyboard: 'shift l' }, - { id: 'info', title: 'Hide Info', keyboard: 'shift i' }, - { id: 'groups', title: 'Hide Groups', keyboard: 'shift g' }, - { id: 'movies', title: 'Hide Movies', disabled: true, keyboard: 'shift m' } - ]}, - { id: 'sortMenu', title: 'Sort', items: [ - { id: 'sortmovies', title: 'Sort Movies by', items: [ - { group: 'sortmovies', min: 1, max: 1, items: $.map(app.config.sortKeys, function(key, i) { - return $.extend({ - checked: app.user.ui.sort[0].key == key.id, - }, key); - }) } - ] }, - { id: 'ordermovies', title: 'Order Movies', items: [ - { group: 'ordermovies', min: 1, max: 1, items: [ - { id: 'ascending', title: 'Ascending', checked: app.user.ui.sort[0].operator === '' }, - { id: 'descending', title: 'Descending', checked: app.user.ui.sort[0].operator == '-' } - ]} - ] }, - { id: 'advancedsort', title: 'Advanced Sort...', keyboard: 'shift control s' }, - {}, - { id: 'groupsstuff', title: 'Groups Stuff' } - ] }, - { id: 'findMenu', title: 'Find', items: [ - { id: 'find', title: 'Find', items: [ - { group: 'find', min: 1, max: 1, items: $.map(app.config.findKeys, function(key, i) { - return $.extend({ - checked: app.user.ui.findQuery.conditions.length && - (app.user.ui.findQuery.conditions[0].key == key.id || - (app.user.ui.findQuery.conditions[0].key === '' && key.id == 'all')), - }, key) - }) } - ] }, - { id: 'advancedfind', title: 'Advanced Find...', keyboard: 'shift control f' } - ] }, - { id: 'dataMenu', title: 'Data', items: [ - { id: 'titles', title: 'Manage Titles...' }, - { id: 'names', title: 'Manage Names...' }, - {}, - { id: 'posters', title: 'Manage Stills...' }, - { id: 'posters', title: 'Manage Posters...' }, - {}, - { id: 'places', title: 'Manage Places...' }, - { id: 'events', title: 'Manage Events...' }, - {}, - { id: 'users', title: 'Manage Users...' }, - { id: 'lists', title: 'Manage Lists...' }, - ] }, - { id: 'codeMenu', title: 'Code', items: [ - { id: 'download', title: 'Download' }, - { id: 'contribute', title: 'Contribute' }, - { id: 'report', title: 'Report a Bug' }, - ] }, - { id: 'helpMenu', title: 'Help', items: [ - { id: 'help', title: app.config.site.name + ' Help', keyboard: 'shift ?' } - ] }, - { id: 'debugMenu', title: 'Debug', items: [ - { id: 'query', title: 'Show Query' } - ] }, - { id: 'testMenu', title: 'Test', items: [ - { group: 'foogroup', items: [ - { id: 'item1', title: 'Item 1' }, - { id: 'item2', title: 'Item 2' } - ] } - ] } - ] - }) - .bindEvent({ - change: function(event, data) { - if (data.id == 'find') { - var id = data.checked[0].id; - app.$ui.findSelect.selectItem(id); - } else if (data.id == 'movieview') { - var view = data.checked[0].id; - var id = document.location.pathname.split('/')[1]; - if (view == 'info') - app.url('/'+id+'/info'); - else - app.url('/'+id); - } else if (data.id == 'ordermovies') { - var id = data.checked[0].id; - app.$ui.list.sortList(user.ui.sort[0].key, id == 'ascending' ? '' : '-'); - } else if (data.id == 'sortmovies') { - var id = data.checked[0].id, - operator = Ox.getObjectById(app.config.sortKeys, id).operator; - app.$ui.mainMenu.checkItem('sortMenu_ordermovies_' + (operator === '' ? 'ascending' : 'descending')); - app.$ui.list.sortList(id, operator); - } else if (data.id == 'viewmovies') { - var view = data.checked[0].id; - app.url('/#view='+view); - } - }, - click: function(event, data) { - if (data.id == 'about') { - var $dialog = new Ox.Dialog({ - buttons: [ - { - click: function() { - $dialog.close(); - }, - id: 'close', - title: 'Close' - } - ], - id: 'about', - title: 'About' - }).open(); - } else if (data.id == 'home') { - var $dialog = new Ox.Dialog({ - buttons: [ - { - click: function() { - $dialog.close(); - }, - id: 'close', - title: 'Close' - } - ], - height: 498, - id: 'home', - title: app.options('name'), - width: 800 - }).open(); - } else if (data.id == 'loginlogout') { - var $form = new Ox.Form({ - error: 'Unknown username or wrong password', - id: 'login', - items: [ - { - element: new Ox.Input({ - autovalidate: function(value, blur, callback) { - var length = value.length; - value = $.map(value.toLowerCase().split(''), function(v, i) { - if (new RegExp('[a-z0-9' + ((i == 0 || (i == length - 1 && blur)) ? '' : '\- ') + ']')(v)) { - return v - } else { - return null; - } - }).join(''); - $.each(['--', '- ', ' -', '--'], function(i, v) { - while (value.indexOf(v) > -1) { - value = value.replace(new RegExp(v, 'g'), v[0]); - } - }) - callback(value); - }, - id: 'username', - label: 'Username', - labelWidth: 120, - validate: function(value, callback) { - pandora.api.findUser({ - key: 'username', - value: value, - operator: '=' - }, function(result) { - Ox.print('result', result) - var valid = result.data.users.length == 1; - callback({ - message: 'Unknown Username', - valid: valid - }); - }); - }, - width: 300 - }) - }, - { - element: new Ox.Input({ - id: 'password', - label: 'Password', - labelWidth: 120, - type: 'password', - validate: /.+/, - width: 300 - }) - } - ], - submit: function(data, callback) { - pandora.api.login(data, function(result) { - if (result.status.code == 200) { - $dialog.close(); - app.user = result.data.user; - app.$ui.mainMenu.getItem('username').options({ - title: 'User: ' + app.user.name - }); - app.$ui.mainMenu.getItem('preferences').options({ - disabled: false - }); - app.$ui.mainMenu.getItem('register').options({ - disabled: true - }); - } else { - callback([{ id: 'password', message: 'Incorrect Password' }]); - } - }); - } - }) - .bindEvent({ - validate: function(event, data) { - $dialog[(data.valid ? 'enable' : 'disable') + 'Button']('signin'); - } - }), - $dialog = new Ox.Dialog({ - buttons: [ - [ - { - click: function() { - - }, - id: 'signup', - title: 'Sign up...' - }, - { - click: function() { - - }, - id: 'reset', - title: 'Reset Password...' - } - ], - [ - { - click: function() { - $dialog.close(); - app.$ui.mainMenu.getItem('loginlogout').toggleTitle(); - }, - id: 'cancel', - title: 'Cancel' - }, - { - click: $form.submit, - disabled: true, - id: 'signin', - title: 'Sign in' - } - ] - ], - id: 'login', - minWidth: 332, - title: 'Sign in', - width: 332 - }).append($form).open(); - } else if (data.id == 'places') { - var $manage = new Ox.SplitPanel({ - elements: [ - { - collapsible: true, - element: new Ox.SplitPanel({ - elements: [ - { - element: new Ox.Toolbar({ - orientation: 'horizontal', - size: 44 - }).append( - app.$ui.findPlacesElement = new Ox.FormElementGroup({ - elements: [ - app.$ui.findPlacesSelect = new Ox.Select({ - id: 'findPlacesSelect', - items: [ - { id: 'name', title: 'Find: Name' }, - { id: 'region', title: 'Find: Region' }, - { id: 'user', title: 'Find: User' } - ], - overlap: 'right', - type: 'image' - }) - .bindEvent({ - change: function(event, data) { - app.$ui.findPlacesSelect.loseFocus(); - app.$ui.findPlacesInput.options({ - placeholder: data.selected[0].title - }); - } - }), - app.$ui.findPlacesInput = new Ox.Input({ - clear: true, - id: 'findPlacesInput', - placeholder: 'Find: Name', - width: 234 - }) - ], - id: 'findPlacesElement' - }) - .css({ - float: 'left', - margin: '4px' - }) - ).append( - app.$ui.sortPlacesSelect = new Ox.Select({ - id: 'sortPlacesSelect', - items: [ - { id: 'name', title: 'Sort by Name', checked: true }, - { id: 'region', title: 'Sort by Region' }, - { id: 'size', title: 'Sort by Size' }, - { id: 'latitude', title: 'Sort by Latitude' }, - { id: 'longitude', title: 'Sort by Longitude' }, - { id: 'clips', title: 'Sort by Number of Clips' }, - { id: 'user', title: 'Sort by User' }, - { id: 'datecreated', title: 'Sort by Date Added' }, - { id: 'datemodified', title: 'Sort by Date Modified' } - ], - width: 246 - }) - .css({ - float: 'left', - margin: '0 4px 4px 4px' - }) - ), - size: 44 - }, - { - element: new Ox.Element('div') - }, - { - element: new Ox.Toolbar({ - orientation: 'horizontal', - size: 16 - }), - size: 16 - } - ], - orientation: 'vertical' - }), - size: 256 - }, - { - element: new Ox.SplitPanel({ - elements: [ - { - element: new Ox.Toolbar({ - orientation: 'horizontal', - size: 24 - }).append( - app.$ui.labelsButton = new Ox.Button({ - id: 'labelsButton', - title: [ - {id: 'show', title: 'Show Labels'}, - {id: 'hide', title: 'Hide Labels'} - ], - width: 96 - }) - .css({ - float: 'left', - margin: '4px' - }) - ).append( - app.$ui.findMapInput = new Ox.Input({ - clear: true, - id: 'findMapInput', - placeholder: 'Find on Map', - width: 192 - }) - .css({ - float: 'right', - margin: '4px' - }) - .bindEvent({ - submit: function(event, data) { - app.$ui.map.find(data.value, function(location) { - app.$ui.placeNameInput.options({ - disabled: false, - value: location.name - }); - app.$ui.placeAliasesInput.options({ - disabled: false - }); - app.$ui.placeGeonameLabel.options({ - disabled: false, - title: location.names.join(', ') - }); - app.$ui.removePlaceButton.options({ - disabled: false - }); - app.$ui.addPlaceButton.options({ - disabled: false - }); - }); - } - }) - ), - size: 24 - }, - { - element: app.$ui.map = new Ox.Map({ - places: ['Boston', 'Brussels', 'Barcelona', 'Berlin', 'Beirut', 'Bombay', 'Bangalore', 'Beijing'] - }) - .css({ - left: 0, - top: 0, - right: 0, - bottom: 0 - }) - .bindEvent({ - select: function(event, location) { - app.$ui.placeNameInput.options({ - disabled: false, - value: location.name - }); - app.$ui.placeAliasesInput.options({ - disabled: false - }); - app.$ui.placeGeonameLabel.options({ - disabled: false, - title: location.names.join(', ') - }); - app.$ui.removePlaceButton.options({ - disabled: false - }); - app.$ui.addPlaceButton.options({ - disabled: false - }); - } - }) - }, - { - element: app.$ui.bottomBar = new Ox.Toolbar({ - orientation: 'horizontal', - size: 24 - }) - .append( - app.$ui.placeNameInput = new Ox.Input({ - disabled: true, - id: 'placeName', - placeholder: 'Name', - width: 128 - }) - .css({ - float: 'left', - margin: '4px 0 0 4px' - }) - ) - .append( - app.$ui.placeAliasesInput = new Ox.Input({ - disabled: true, - id: 'aliases', - placeholder: 'Aliases', - width: 128 - }) - .css({ - float: 'left', - margin: '4px 0 0 4px' - }) - ) - .append( - app.$ui.placeGeonameLabel = new Ox.Label({ - disabled: true, - id: 'placeGeoname', - title: 'Geoname', - width: parseInt(app.$document.width() * 0.8) - 256 - 256 - 32 - 24 - }) - .css({ - float: 'left', - margin: '4px 0 0 4px' - }) - ) - .append( - app.$ui.addPlaceButton = new Ox.Button({ - disabled: true, - id: 'addPlaceButton', - title: 'add', - type: 'image' - }) - .css({ - float: 'right', - margin: '4px 4px 0 0' - }) - ) - .append( - app.$ui.removePlaceButton = new Ox.Button({ - disabled: true, - id: 'removePlaceButton', - title: 'remove', - type: 'image' - }) - .css({ - float: 'right', - margin: '4px 4px 0 0' - }) - ), - size: 24 - } - ], - orientation: 'vertical' - }) - } - ], - orientation: 'horizontal' - }).css({ - top: '24px', - bottom: '24px', - }), - $dialog = new Ox.Dialog({ - buttons: [ - { - click: function() { - $dialog.close(); - }, - id: 'close', - title: 'Close', - value: 'Close' - } - ], - height: parseInt(app.$document.height() * 0.8), - id: 'places', - minHeight: 400, - minWidth: 600, - padding: 0, - title: 'Manage Places', - width: parseInt(app.$document.width() * 0.8) - }).css({ - overflow: 'hidden' - }).append($manage).open(); - } - } - }); -} - -app.constructSectionbar = function() { - return new Ox.Bar({ - size: 24 - }) - .append( - app.$ui.sectionButtons = new Ox.ButtonGroup({ - buttons: [ - {id: 'site', title: app.config.site.name}, - {id: 'items', title: app.config.itemName.plural}, - {id: 'texts', title: 'Texts'}, - {id: 'admin', title: 'Admin', type: 'image'} - ], - id: 'sectionButtons', - selectable: true - }) - .css({ - float: 'left', - margin: '4px' - }) - ); -} - -app.constructSections = function() { - var $sections = []; - $.each(app.user.ui.sections, function(i, id) { - var $section = new Ox.CollapsePanel({ - id: id, - size: 16, - title: Ox.getObjectById(app.config.sections, id).title - }); - $sections.push($section); - $section.$content.append( - $('
').css({ height: '20px' }).append( - $('
').css({ float: 'left', width: '16px', height: '16px', margin: '1px'}).append( - $('').attr({ src: 'static/oxjs/build/png/ox.ui.modern/iconFind.png' }).css({ width: '16px', height: '16px', border: 0, background: 'rgb(64, 64, 64)', WebkitBorderRadius: '2px' }) - ) - ).append( - $('
').css({ float: 'left', width: '122px', height: '14px', margin: '2px' }).html('Foo') - ).append( - $('
').css({ float: 'left', width: '40px', height: '14px', margin: '2px', textAlign: 'right' }).html('23') - ) - ); - }); - return $sections; -} - -app.constructStatusbar = function() { - return new Ox.Bar({ - size: 16 - }) - .css({ - textAlign: 'center' - }) - .append( - new Ox.Element() - .css({ - marginTop: '2px', - fontSize: '9px' - }) - .append( - app.$ui.total = new Ox.Element('span') - ) - .append( - new Ox.Element('span').html(' — ') - ) - .append( - app.$ui.selected = new Ox.Element('span') - ) - ); -} - -app.constructStatus = function(key, data) { - return Ox.toTitleCase(key) + ': ' + [ - Ox.formatNumber(data.items) + ' movie' + (data.items != 1 ? 's' : ''), - Ox.formatDuration(data.runtime, 'medium'), - data.files + ' file' + (data.files != 1 ? 's' : ''), - Ox.formatDuration(data.duration, 'short'), - Ox.formatValue(data.size, 'B'), - Ox.formatValue(data.pixels, 'px') - ].join(', '); -} - -app.constructToolbar = function() { - return new Ox.Bar({ - size: 24 - }) - .append( - app.$ui.groupsButton = new Ox.Button({ - id: 'groupsButton', - title: [ - {id: 'show', title: 'Show Groups'}, - {id: 'hide', title: 'Hide Groups'} - ], - width: 96 - }) - .css({ - float: 'left', - margin: '4px' - }) - ) - .append( - app.$ui.viewSelect = new Ox.Select({ - id: 'viewSelect', - items: $.map(app.config.listViews, function(view, i) { - view.title = 'View ' + view.title - return $.extend({ - checked: app.user.ui.listView == view.id, - }, view); - }), - width: 144 - }) - .css({ - float: 'left', - margin: '4px' - }) - .bindEvent('change', function(event, data) { - var id = data.selected[0].id; - app.$ui.mainMenu.checkItem('viewMenu_movies_' + id); - //$ui.list.$element.replaceWith(constructList(id)); - Ox.print('change ... id', id, list = app.constructList(id), list.options(), list.options('id')) - //$ui.contentPanel.replace('list', constructList(id)); - app.$ui.contentPanel.replace(1, app.constructList(id)); - }) - ) - .append( - app.$ui.findElement = new Ox.FormElementGroup({ - elements: [ - app.$ui.findSelect = new Ox.Select({ - id: 'select', - items: $.map(app.config.findKeys, function(key, i) { - return { - id: key.id, - title: 'Find: ' + key.title - }; - }), - overlap: 'right', - width: 112 - }) - .bindEvent('change', function(event, data) { - var key = data.selected[0].id; - app.user.ui.findQuery.conditions[0].key = key - app.$ui.mainMenu.checkItem('findMenu_find_' + key); - app.$ui.findInput.focus(); - }), - app.$ui.findInput = new Ox.Input({ - autocomplete: function(value, callback) { - var key = 'title'; - var findKey = Ox.getObjectById(app.config.findKeys, key); - Ox.print('autocomplete', key, value); - value === '' && Ox.print('Warning: autocomplete function should never be called with empty value'); - if ('autocomplete' in findKey && findKey.autocomplete) { - pandora.api.find({ - keys: [key], - query: { - conditions: [ - { - key: key, - value: value, - operator: '' - } - ], - operator: '' - }, - sort: [ - { - key: key, - operator: '' - } - ], - range: [0, 10] - }, function(result) { - callback($.map(result.data.items, function(v) { - return v.title; - })); - }); - } else { - callback(); - } - }, - autocompleteSelect: true, - autocompleteSelectHighlight: true, - autocompleteSelectSubmit: true, - clear: true, - id: 'input', - width: 192 - }) - .bindEvent('submit', function(event, data) { - var key = app.user.ui.findQuery.conditions[0].key, - query; - Ox.print('key', key); - app.user.ui.findQuery.conditions = [ - { - key: key == 'all' ? '' : key, - value: data.value, - operator: '' - } - ]; - $.each(app.ui.groups, function(i, group) { - group.query.conditions = []; - app.$ui.groups[i].options({ - request: function(data, callback) { - delete data.keys; - return pandora.api.find($.extend(data, { - group: group.id, - query: app.Query.toObject(group.id) - }), callback); - } - }); - }); - app.$ui.list.options({ - request: function(data, callback) { - return pandora.api.find($.extend(data, { - query: query = app.Query.toObject() - }), callback); - } - }); - history.pushState({}, '', '/#' + app.Query.toString(query)); - }) - ], - id: 'findElement' - }) - .css({ - float: 'right', - margin: '4px' - }) - ); -} - -*/ - - - -/* - - //FIXME: how to properly overwrite functions without replacing them - var super_launch = app.launch; - app.launch = function() { - app.request.send('hello', function(result) { - app.user = result.data.user; - if(app.user.group!='guest') { - app.menu.getItem('status').options('title', 'User: ' + app.user.username); - app.menu.getItem('login').options('title', 'Logout'); - } - }); - super_launch(); - }; - - - var loadingIcon = new Ox.LoadingIcon({ - size: 'medium' - }) - .css({ - marginLeft: '4px' - }); - - app.menu = new Ox.MainMenu({ - extras: [ - new Ox.Input({ - autocomplete: function(option, value, callback) { - var field = option.substring(6).toLowerCase(); - if(typeof(callback) == 'undefined') { - callback = value; - value = null; - } - Ox.debug('app.menu.find.autocomplete: option: ', option, 'value: ', value, ', callback:',callback); - Ox.debug('app.menu.find.autocomplete: field: ', field); - if(field == 'all') { - callback([]); - } else if (value) { - value = value.toLowerCase(); - //var order = $.inArray(field, ['year', 'date'])?'-':''; - app.request.send('find', { - query: { - conditions: [ - { - key: field, - value: value, - operator: '~' - } - ] - }, - list: 'all', - sort: [{key:field, operator: ''}], - keys: [field], - range: [0, 10] - }, function(result) { - var items = $.map( - result.data.items, - function(item, i) { return item.title; } - ); - callback(items); - }); - } - }, - clear: true, - highlight: false, - id: 'find', - label: [ - { id: 'all', title: 'Find: All' }, - { id: 'title', title: 'Find: Title' }, - { id: 'director', title: 'Find: Director' }, - { id: 'country', title: 'Find: Country' }, - { id: 'year', title: 'Find: Year' }, - { id: 'language', title: 'Find: Language' }, - { id: 'writer', title: 'Find: Writer' }, - { id: 'producer', title: 'Find: Producer' }, - { id: 'cinematographer', title: 'Find: Cinematographer' }, - { id: 'editor', title: 'Find: Editor' }, - { id: 'actor', title: 'Find: Actor' }, - { id: 'character', title: 'Find: Character' }, - { id: 'name', title: 'Find: Name' }, - { id: 'genre', title: 'Find: Genre' }, - { id: 'keyword', title: 'Find: Keyword' }, - { id: 'summary', title: 'Find: Summary' }, - { id: 'dialog', title: 'Find: Dialog' } - ], - labelWidth: 96 - }).width(320), - loadingIcon - ], - menus: [ - { - id: 'pandoraMM', - title: site.name, - items: [ - { id: 'about', title: 'About ' + site.name }, - {}, - { id: 'faq', title: 'Frequently Asked Questions'}, - { id: 'tos', title: 'Terms of Service'}, - { id: 'sas', title: 'Security Advisory System'}, - {}, - { id: 'contact', title: 'Contact'}, - {}, - { id: 'technology', title: 'Technology'}, - { id: 'source', title: 'Source Code'}, - { id: 'report', title: 'Report a Bug...'}, - ] - }, - { - id: 'user', - id: 'user', - title: 'User', - items: [ - { id: 'status', title: 'User: not logged in', disabled:true }, - {}, - { id: 'accunt', title: 'Account', disabled:true}, - { id: 'preferences', title: 'Preferences', disabled:true}, - {}, - {id: 'login', title: 'Login'}, - ] - }, - { - id: 'file', - title: 'File', - items: [ - { id: 'load', keyboard: 'control o', title: 'Open' }, - { id: 'save', keyboard: 'control a', title: 'Save' }, - { id: 'save_ad', keyboard: 'shift control s', title: 'Save As...'} - ] - }, - { - id: 'edit', - title: 'Edit', - items: [ - { id: 'undo', keyboard: 'control z', title: 'Undo' }, - { id: 'redo', keyboard: 'shift control z', title: 'Redo' }, - {}, - { id: 'cut', keyboard: 'control x', title: 'Cut' }, - { id: 'copy', keyboard: 'control c', title: 'Copy' }, - { id: 'paste', keyboard: 'control v', title: 'Paste'}, - { id: 'delete', keyboard: 'delete', title: 'Delete'}, - {}, - { id: 'select_all', keyboard: 'control a', title: 'Select All' }, - { id: 'select_none', keyboard: 'shift control a', title: 'Select None' }, - { id: 'invert_selection', keyboard: 'alt control a', title: 'Invert Selection' }, - ] - }, - { - id: 'sort', - title: 'Sort', - items: [ - { id: 'sort_movies', title: 'Sort Movies by', items: [ - { checked: true, group: 'sort_movies', id: 'title', title: 'Title'}, - { checked: false, group: 'sort_movies', id: 'director', title: 'Director' }, - ] }, - { id: 'order_movies', title: 'Order Movies', items: [ - { checked: false, group: 'order_movies', id: 'ascending', title: 'Ascending'}, - { checked: true, group: 'order_movies', id: 'descending', title: 'Descending' }, - ] } - ] - }, - { - id: 'help', - title: 'Help', - items: [ - { id: 'help', keyboard: 'control h', title: 'Help' } - ] - } - ], - size: 'large' - }); - - function pageDialog(title, page) { - //Ox.debug(title, page); - var $dialog = new Ox.Dialog({ - title: title, - buttons: [ - { - title: 'Close', - click: function() { $dialog.close(); } - } - ] - }) - .append(page) - .open(); - }; - //this should be: mainMenu.bind('click_about', function(event) { - app.menu.bindEvent('click_about', function() { - pageDialog('About ' + site.name, site.pages.about); - }); - app.menu.bindEvent('click_faq', function() { - pageDialog(app.menu.getItem('faq').options('title')[0], - site.pages.faq); - }); - app.menu.bindEvent('click_tos', function() { - pageDialog(app.menu.getItem('tos').options('title')[0], - site.pages.tos); - }); - app.menu.bindEvent('click_sas', function() { - pageDialog(app.menu.getItem('sas').options('title')[0], - site.pages.sas); - }); - - OxForm = function(options, self) { - var self = self || {}, - that = new Ox.Element({}, self) - .defaults({ - elements: [], - }) - .options(options || {}) - .addClass('OxForm'), - length = self.options.elements.length; - $.each(self.options.elements, function(i, v) { - that.append(Ox.Container().css({'margin': '5px'}).append(v)); - }); - that.values = function() { - var values = {}; - $.each(self.options.elements, function(i, v) { - values[v.$input.attr('name')] = v.$input.val(); - }); - return values; - } - return that; - }; - - app.menu.bindEvent('click_contact', function() { - var labelWidth = 64; - var inputWidth = 380; - - var u = new Ox.Input({ - label: 'Your Email', - labelWidth: labelWidth, - name:'email', - size: 'medium' - }).width(inputWidth).addClass('margin'); - if(app.user && app.user.preferences.email) { - u.val(app.user.preferences.email); - } - - var form = new OxForm({ - elements: [ - u, - new Ox.Input({ - label: 'Subject', - labelWidth: labelWidth, - name: 'subject', - size: 'medium' - }).width(inputWidth).addClass('margin'), - new Ox.Input({ - label: 'Message', - labelWidth: labelWidth, - type: 'textarea', - size: 'medium', - name: 'message' - }).width(380).height(176).addClass('margin') - ] - }); - - var $dialog = new Ox.Dialog({ - title: 'Contact', - width: 424, - height: 320, - buttons: [ - { - value: 'Cancel', - click: function() { $dialog.close(); } - }, - { - value: 'Contact', - click: function() { - app.request.send('contact', form.values(), - function(result) { - if(result.status.code == 200) { - $dialog.close(); - } else { - $dialog.append(result.status.text); - } - }); - } - } - ] - }) - .append(form) - .open(); - }); - app.menu.bindEvent('click_technology', function() { - pageDialog(app.menu.getItem('technology').options('title')[0], - site.pages.technology); - }); - app.menu.bindEvent('click_source', function() { - pageDialog(app.menu.getItem('source').options('title')[0], - site.pages.source); - }); - app.menu.bindEvent('click_report', function() { - pageDialog(app.menu.getItem('report').options('title')[0], - site.pages.report); - }); - - app.logout = function () { - this.request('logout'); - this.user = {}; - this.menu.getItem('logout').toggle(); - this.menu.getItem('status').options('title', 'User: not logged in'); - }; - app.menu.bindEvent('click_logout', function(event, data) { - app.logout(); - }); - - app.menu.bindEvent('click_login', function(element) { - var labelWidth = 64; - var inputWidth = labelWidth+200; - var loginForm = new OxForm({ - elements: [ - new Ox.Input({ - label: 'Username', - labelWidth: labelWidth, - name:'username', - size: 'medium' - }).addClass('margin').width(inputWidth), - new Ox.Input({ - label: 'Password', - labelWidth: labelWidth, - name:'password', - type: 'password', - size: 'medium' - }).addClass('margin').width(inputWidth) - ] - }).css({ - 'padding-top': '48px', - }); - - var submit = function() { - app.request.send('login', loginForm.values(), function(result) { - if(result.status.code == 200) { - $dialog.close(); - app.user = result.data.user; - app.menu.getItem('status').options(title, 'User: ' + app.user.username); - app.menu.getItem('login').toggle(); - - } else { - $dialog.append('Login failed ' + result.status.text); - } - }); - } - - var d = new Ox.Container(); - var registerInfo = new Ox.Panel(); - - registerInfo.append(Ox.Element().css({'margin-left': '4px'}).append('
Forgot your password? Recover Password
Dont have an account? Register Now')); - - var panel = Ox.SplitPanel({ - elements: [ - { - element: loginForm, - }, - { - element: registerInfo, - size: 80 - } - ], - orientation: 'vertical' - }).appendTo(d); - - var $dialog = new Ox.Dialog({ - title: 'Login', - width: inputWidth+24, - height: 184, - buttons: [ - [],[ - { - value: 'Cancel', - click: function() { $dialog.close(); } - }, - { - value: 'Login', - click: submit - } - ] - ] - }) - .append(d) - .open(); - }); - var bottomPanel = Ox.Toolbar({size: 'small'}) - .css({ - zIndex: 2, - MozBoxShadow: '0 0 4px rgb(0, 0, 0)', - WebkitBoxShadow: '0 0 4px rgb(0, 0, 0)' - }) - .append( - $('
') - .addClass('bottom') - .html(site.url + ' - a rather unique kind of movie database.') - ); - var mainSplitPanel = Ox.SplitPanel({ - elements: [ - { - element: app.menu, - size: 24 - }, - { - element: middleSplitPanel - }, - { - element: bottomPanel, - size: 24 - } - ], - orientation: 'vertical' - }).appendTo($body); - - var listPanel = new Ox.CollapsePanel({ - title: 'Lists' - }).appendTo(sidePanel); - listPanel.$content.html('Nouvelle Vague
Hollywood 40\'s
Pirate Cinema Berlin') - - var historyPanel = new Ox.CollapsePanel({ - title: 'Search History' - }).appendTo(sidePanel); - - historyPanel.$content.html('Paris
Matirx
Godard') - - app.results = new Ox.TextList({ - columns: [ { - align: 'left', - id: 'title', - operator: '+', - title: 'Title', - visible: true, - width: 160 - }, - { - align: 'left', - id: 'director', - operator: '+', - title: 'Director', - visible: true, - width: 160 - }, - { - align: 'right', - id: 'year', - operator: '-', - title: 'Year', - visible: true, - width: 80 - } - ], - request: function(options) { - app.request.send('find', $.extend(options, { - query: { - conditions: [], - operator: ',' // fixme: should be & - } - }), options.callback); - }, - id: 'results', - sort: [{ - key: 'year', - operator: '-' - }] - }).appendTo(content); - - app.menu.bindEvent('submit_find', function(event, data) { - app.results.options({ - request: function(options) { - app.request.send('find', $.extend(options, { - query: { - key: data.option.substr(6).toLowerCase(), - value: data.value, - operator: '~' - } - }), options.callback); - }, - }); - }); - app.launch(); - -}); - -*/ +}); \ No newline at end of file