diff --git a/pandora/home/models.py b/pandora/home/models.py
index 219e6ed1..4031ab9a 100644
--- a/pandora/home/models.py
+++ b/pandora/home/models.py
@@ -3,6 +3,8 @@
from __future__ import division, print_function, absolute_import
from six import string_types
+from six.moves.urllib.parse import quote
+
from django.db import models
from django.db.models import Max
import ox
@@ -42,6 +44,16 @@ class Item(models.Model):
return False
self.data[key] = data[key]
changed = True
+ if 'type' in data:
+ if data['type'] == 'custom':
+ if 'contentid' in self.data:
+ del self.data['contentid']
+ changed = True
+ else:
+ for key in list(self.data):
+ if key not in ('contentid', 'type'):
+ del self.data[key]
+ changed = True
if 'active' in data:
self.active = data['active'] is True
changed = True
@@ -70,17 +82,29 @@ class Item(models.Model):
}
j.update(self.data)
if 'contentid' in j and (not keys or 'content' in keys):
- content_keys = ['description', 'modified', 'name', 'user']
+ content_keys = [
+ 'description',
+ 'modified',
+ 'name',
+ 'user',
+ ]
type = j.get('type')
if type == 'list':
from itemlist.models import List
- j['content'] = List.get(j['contentid']).json(keys=content_keys)
+ content = List.get(j['contentid']).json(keys=content_keys)
elif type == 'edit':
from edit.models import Edit
- j['content'] = Edit.get(j['contentid']).json(keys=content_keys)
+ content = Edit.get(j['contentid']).json(keys=content_keys)
elif type == 'collection':
from documentcollection.models import Collection
- j['content'] = Collection.get(j['contentid']).json(keys=content_keys)
+ content = Collection.get(j['contentid']).json(keys=content_keys)
+ j['title'] = content['name']
+ j['text'] = content['description']
+
+ j['image'] = '/' + '/'.join([
+ type, quote(content['user'] + ':' + content['name']),
+ 'icon256.jpg?%s' % content['modified'].strftime('%Y-%m-%dT%H:%M:%SZ')
+ ])
if keys:
for key in list(j):
if key not in keys:
@@ -88,4 +112,4 @@ class Item(models.Model):
return j
def __unicode__(self):
- return u"%s" %(self.get_id())
+ return u"%s" % (self.get_id())
diff --git a/pandora/home/views.py b/pandora/home/views.py
index 0ea49307..9f3bde59 100644
--- a/pandora/home/views.py
+++ b/pandora/home/views.py
@@ -100,7 +100,7 @@ def getHomeItems(request, data):
}
'''
response = json_response()
- qs = models.Item.objects.all().order_by('index', 'created')
+ qs = models.Item.objects.all().order_by('-active', 'index', 'created')
if 'active' in data:
qs = qs.filter(active=data['active'] is True)
response['data']['items'] = [i.json() for i in qs]
diff --git a/static/js/home.indiancinema.js b/static/js/home.indiancinema.js
index fc06062c..9f495c10 100644
--- a/static/js/home.indiancinema.js
+++ b/static/js/home.indiancinema.js
@@ -329,253 +329,67 @@ pandora.ui.home = function() {
color = Ox.Theme() == 'oxlight' ? 'rgb(0, 0, 0)'
: Ox.Theme() == 'oxmedium' ? 'rgb(0, 0, 0)'
: 'rgb(255, 255, 255)',
- $label, $icon, $text,
+ $label, $texts,
$featuresBox, $featuresContainer, $featuresContent,
$featureBox = [], $featureIcon = [],
$previousButton, $nextButton;
if (items.length) {
- $label = Ox.Label({
- textAlign: 'center',
- title: '' + Ox._('Featured ' + (
- lists == 1 && edits == 0 && texts == 0 ? 'List'
- : lists == 0 && edits == 1 && texts == 0 ? 'Edit'
- : lists == 0 && edits == 0 && texts == 1 ? 'Text'
- : edits == 0 && texts == 0 ? 'Lists'
- : lists == 0 && texts == 0 ? 'Edits'
- : lists == 0 && edits == 0 ? 'Texts'
- : texts == 0 ? 'Lists and Edits'
- : edits == 0 ? 'Lists and Texts'
- : lists == 0 ? 'Edits and Texts'
- : 'Lists, Edits and Texts'
- )) + '',
- width: 512
- })
- .css({
- position: 'absolute',
- left: 0,
- top: 0,
- right: 0,
- bottom: 0,
- margin: '0 auto 0 auto'
- })
- .appendTo($features);
- $text = Ox.Label({
- width: 386
- })
- .addClass('OxSelectable')
- .css({
- position: 'absolute',
- left: '24px',
- top: '24px',
- right: 0,
- height: '104px',
- borderTopLeftRadius: '32px',
- borderBottomLeftRadius: '32px',
- padding: '8px 8px 8px 130px',
- overflowY: 'auto',
- lineHeight: '14px',
- textOverflow: 'ellipsis',
- whiteSpace: 'normal'
- })
- .html(
- getHTML(items[selected])
- )
- .appendTo($features);
- pandora.createLinks($text);
- $icon = Ox.Element({
- element: '',
- tooltip: getTooltip(items[selected])
- })
- .attr({
- src: getImageURL(items[selected])
- })
- .css({
- position: 'absolute',
- left: 0,
- top: '24px',
- right: '390px',
- width: '122px',
- height: '122px',
- borderRadius: '32px',
- margin: '0 auto 0 auto',
- cursor: 'pointer'
- })
- .bindEvent({
- anyclick: function() {
- openItem(selected);
- }
- })
- .appendTo($features);
- if (items.length > 1) {
- $featuresBox = $('
')
+ $features.empty();
+ $texts = Ox.Element().appendTo($features);
+ var top = 24;
+ items.forEach(function(item) {
+ var $text, $icon;
+ $icon = Ox.Element({
+ element: '
',
+ tooltip: getTooltip(item)
+ })
+ .attr({
+ src: item.image
+ })
.css({
- position: 'absolute',
left: 0,
- top: '150px',
- right: 0,
- height: '65px', // 4+57+4
- width: '560px', // 16+8+512+8+16
- margin: '0 auto 0 auto'
+ right: '390px',
+ width: '122px',
+ height: '122px',
+ borderRadius: '32px',
+ marginRight: '8px',
+ cursor: 'pointer',
+ float: 'left'
})
- .appendTo($features);
- $featuresContainer = $('
')
- .css({
- position: 'absolute',
- left: '20px',
- right: '20px',
- height: '65px',
- width: '520px',
- overflow: 'hidden'
- })
- .appendTo($featuresBox);
- $featuresContent = $('
')
- .css({
- position: 'absolute',
- width: items.length * 65 + 'px',
- height: '65px',
- marginLeft: items.length < max
- ? (max - items.length) * 65 / 2 + 'px'
- : 0
- })
- .appendTo($featuresContainer);
- if (items.length > max) {
- $previousButton = Ox.Button({
- title: 'left',
- type: 'image'
- })
- .addClass(position > 0 ? 'visible' : '')
- .css({
- position: 'absolute',
- left: 0,
- top: '25px',
- opacity: 0
- })
- .hide()
- .bindEvent({
- mousedown: function() {
- counter = 0;
- scrollToPosition(position - 1, true);
- },
- mouserepeat: function() {
- // fixme: arbitrary
- if (counter++ % 5 == 0) {
- scrollToPosition(position - 1, false);
- }
- }
- })
- .appendTo($featuresBox);
- $nextButton = Ox.Button({
- title: 'right',
- type: 'image'
- })
- .addClass(position < items.length - 1 ? 'visible' : '')
- .css({
- position: 'absolute',
- right: 0,
- top: '25px',
- opacity: 0
- })
- .hide()
- .bindEvent({
- mousedown: function() {
- counter = 0;
- scrollToPosition(position + 1, true);
- },
- mouserepeat: function() {
- // fixme: arbitrary
- if (counter++ % 5 == 0) {
- scrollToPosition(position + 1, false);
- }
- }
- })
- .appendTo($featuresBox);
- $featuresBox.on({
- mouseenter: function() {
- mouse = true;
- $('.visible').show().stop().animate({
- opacity: 1
- }, 250);
- },
- mouseleave: function() {
- mouse = false;
- $('.visible').stop().animate({
- opacity: 0
- }, 250, function() {
- $(this).hide();
- });
- },
- mousewheel: function(e, delta, deltaX, deltaY) {
- // fixme: arbitrary
- scrollToPosition(position + Math.round(deltaX * 2), true);
+ .bindEvent({
+ anyclick: function() {
+ openItem(item);
}
});
- }
- items.forEach(function(item, i) {
- $featureBox[i] = $('
')
- .css({
- float: 'left',
- width: '57px',
- height: '57px',
- padding: '2px',
- margin: '2px',
- borderRadius: '16px',
- boxShadow: '0 0 2px ' + (i == selected ? color : 'transparent')
- })
- .appendTo($featuresContent);
- $featureIcon[i] = Ox.Element({
- element: '
',
- tooltip: (
- (lists && edits) || (lists && texts) || (edits && texts)
- ? Ox._(Ox.toTitleCase(item.type)) + ': '
- : ''
- )
- + Ox.encodeHTMLEntities(item.name)
- })
- .attr({
- src: getImageURL(item)
- })
- .css({
- width: '57px',
- height: '57px',
- borderRadius: '16px',
- cursor: 'pointer'
- })
- .bindEvent({
- doubleclick: function() {
- openItem(i);
- },
- singleclick: function() {
- selectItem(i);
- }
- })
- .appendTo($featureBox[i]);
- });
- self.keydown = function(e) {
- var key = Ox.KEYS[e.keyCode];
- if (!Ox.Focus.focusedElementIsInput()) {
- if (key == 'left' && selected > 0) {
- selectItem(selected - 1);
- } else if (key == 'up' && selected > 0) {
- selectItem(0);
- } else if (key == 'right' && selected < items.length - 1) {
- selectItem(selected + 1);
- } else if (key == 'down' && selected < items.length - 1) {
- selectItem(items.length - 1);
- }
- }
- };
- Ox.$document.on({keydown: self.keydown});
- }
- $space = $('
')
- .css({
- position: 'absolute',
- top: items.length == 0 ? '0px'
- : items.length == 1 ? '150px'
- : '215px',
- width: '560px',
- height: '80px'
- })
- .appendTo($features);
+ $text = Ox.Label({
+ //width: 386 + 122
+ })
+ .addClass('OxSelectable')
+ .css({
+ //position: 'absolute',
+ left: '24px',
+ //top: top + 'px',
+ right: 0,
+ height: 'auto',
+ padding: '8px 8px 8px 8px',
+ borderRadius: '32px',
+ marginBottom: '16px',
+ overflowY: 'auto',
+ lineHeight: '14px',
+ textOverflow: 'ellipsis',
+ whiteSpace: 'normal'
+ })
+ .append($icon)
+ .append(
+ Ox.Element().css({
+ //padding: '8px',
+ }).html(getHTML(item))
+
+ )
+ .appendTo($texts);
+ pandora.createLinks($text);
+ top += 130;
+ });
$features.animate({opacity: 1}, 250);
}
@@ -589,44 +403,44 @@ pandora.ui.home = function() {
? Ox._(Ox.toTitleCase(item.type)) + ': '
: ''
)
- + Ox.encodeHTMLEntities(item.content.name) + '
'
- + item.content.description;
- }
-
- function getImageURL(item) {
- if (item.type == 'custom') {
- return item.image;
- }
- return '/' + item.type + '/' + item.user
- + ':' + encodeURIComponent(item.name) + '/icon256.jpg?' + item.modified;
+ + Ox.encodeHTMLEntities(item.title) + '
'
+ + item.text;
}
function getTooltip(item) {
- return Ox._('View {0}', [Ox._(Ox.toTitleCase(item.type))])
+ return Ox._('View {0}', [Ox._(Ox.toTitleCase(item.title))])
}
- function openItem(i) {
+ function openItem(item) {
that.fadeOutScreen();
- if (items[i].type == 'custom') {
- pandora.URL.push(items[i].link);
+ if (item.type == 'custom') {
+ pandora.URL.push(item.link);
} else {
pandora.UI.set(Ox.extend({
- section: items[i].type == 'list' ? 'items' : items[i].type + 's',
+
+ section: item.type == 'list' ? 'items' : item.type + 's',
page: ''
- }, items[i].type == 'list' ? {
+ }, item.type == 'list' ? {
find: {
conditions: [{
key: 'list',
- value: items[i].content.user + ':'
- + items[i].content.name,
+ value: item.contentid,
operator: '=='
}],
operator: '&'
}
- } : items[i].type == 'edit' ? {
- edit: items[i].content.user + ':' + items[i].content.name
+ } : item.type == 'collection' ? {
+ findDocuments: {
+ conditions: [{
+ key: 'collection',
+ value: item.contentid,
+ operator: '=='
+ }],
+ operator: '&'
+ }
+ } : item.type == 'edit' ? {
+ edit: item.contentid
} : {
- text: items[i].content.user + ':' + items[i].content.name
}));
}
}
@@ -661,31 +475,6 @@ pandora.ui.home = function() {
});
}
}
-
- function selectItem(i) {
- if (i >= 0 && i <= items.length - 1 && i != selected) {
- $featureBox[selected].css({
- boxShadow: 'none'
- });
- selected = i;
- $featureBox[selected].css({
- boxShadow: '0 0 2px ' + color
- });
- if (selected < position) {
- scrollToPosition(selected, true);
- } else if (selected > position + max - 1) {
- scrollToPosition(selected - max + 1, true);
- }
- $icon.attr({
- src: getImageURL(items[selected])
- }).options({
- tooltip: getTooltip(items[selected])
- });
- $text.html(
- getHTML(items[selected])
- );
- }
- }
}
}
diff --git a/static/js/homeDialog.js b/static/js/homeDialog.js
index 1d1657a0..0265116b 100644
--- a/static/js/homeDialog.js
+++ b/static/js/homeDialog.js
@@ -2,14 +2,23 @@
pandora.ui.homeDialog = function() {
- var $lists = Ox.Element();
+ var items = [];
- var $item = $('
');
+ var autocompleteData = {};
+
+ var $folders = $('
').css({overflowX: 'hidden', overflowY: 'auto'});
+
+ var $item = $('
').addClass('OxTextPage');
+
+ var $form = $('
');
+
+ var $title, $text, $typeSelect, $imageInput, $linkInput, $nameInput;
var $dialogPanel = Ox.SplitPanel({
elements: [
- {element: $lists, size: 256},
- {element: $item}
+ {element: $folders, resizable: true, resize: [256], size: 256},
+ {element: $item},
+ {element: $form, resizable: true, resize: [256], size: 256}
],
orientation: 'horizontal'
})
@@ -27,28 +36,131 @@ pandora.ui.homeDialog = function() {
],
closeButton: true,
content: $dialogPanel,
- height: 576,
+ height: 256, //576,
removeOnClose: true,
title: Ox._('Manage Home Screen'),
- width: 768
+ width: 1050 // 256 + 17 + 512 + 17 + 256
});
pandora.api.getHomeItems({}, function(result) {
- var $activeList = renderList(result.data.items.filter(function(item) {
- return item.active;
- })).appendTo($lists);
- var $inactiveList = renderList(result.data.items.filter(function(item) {
- return !item.active;
- }))//.appendTo($lists);
- });
+ getAutocompleteData(function() {
+ items = result.data.items;
+ var selected = items.length ? items[0].id : null;
+ renderFolders(result.data.items, selected);
+ if (selected) {
+ var item = Ox.getObjectById(items, selected)
+ renderItem(item);
+ renderForm(item);
+ }
+ });
+ });
- function renderItem(data) {
- var $item = $('
');
- if (!data) {
- return $item;
+ function editItem(id, key, value) {
+ var title = $title.value();
+ var text = $text.value();
+ var type = $typeSelect.value();
+ if (type == 'custom') {
+ var image = $imageInput.value();
+ var link = $linkInput.value();
+ } else {
+ var name = $nameInput.value();
}
- var $form = $('
').appendTo($item);
- var $typeSelect = Ox.Select({
+ if (
+ !title || !text
+ || (type == 'custom' && (!image || !link))
+ || (type != 'custom' && !name)
+ ) {
+ return;
+ }
+ pandora.api.editHomeItem(Ox.extend({id: id}, key, value), function(result) {
+ // ...
+ });
+ }
+
+ function getAutocompleteData(callback) {
+ Ox.parallelForEach(
+ ['list', 'edit', 'collection'],
+ function(value, index, array, callback) {
+ pandora.api['find' + Ox.toTitleCase(value) + 's']({
+ keys: ['id'],
+ query: {
+ conditions: [
+ {key: 'status', operator: '!=', value: 'private'}
+ ],
+ operator: '&'
+ },
+ range: [0, 1000]
+ }, function(result) {
+ autocompleteData[value] = result.data.items.map(function(item) {
+ return item.id;
+ });
+ callback();
+ });
+ },
+ callback
+ );
+ }
+
+ function renderFolder(type, items, selected) {
+ var extras = [
+ Ox.MenuButton({
+ items: [
+ {id: 'newitem', title: Ox._(
+ 'New ' + (type == 'active' ? 'Active' : 'Inactive') + ' Item'
+ )},
+ {id: 'deleteitem', title: Ox._('Delete Selected Item')}
+ ],
+ title: 'edit',
+ tooltip: Ox._('Manage Items'),
+ type: 'image'
+ }).bindEvent({
+ click: function(data) {
+ if (data.id == 'newitem') {
+ // ...
+ } else if (data.id == 'deleteitem') {
+ // ...
+ }
+ }
+ })
+ ];
+ var $folder = Ox.CollapsePanel({
+ collapsed: false,
+ extras: extras,
+ size: 16,
+ title: Ox._((type == 'active' ? 'Active' : 'Inactive') + ' Items')
+ }).bindEvent({
+ toggle: function(data) {
+ data.collapsed && $list.loseFocus();
+ }
+ });
+ var $placeholder = Ox.Element().addClass('OxLight').css({
+ height: '14px',
+ padding: '1px 4px',
+ }).html(Ox._('No items')).hide().appendTo($folder.$content)
+ var $list = renderList(items.filter(function(item) {
+ return item.active == (type == 'active');
+ }), selected).bindEventOnce({
+ init: function(data) {
+ $placeholder[data.items ? 'hide' : 'show']();
+ $folder.$content.css({
+ height: (data.items || 1) * 16 + 'px'
+ });
+ }
+ }).appendTo($folder.$content);
+
+ return $folder;
+ }
+
+ function renderFolders(items, selected) {
+ $folders.empty();
+ ['active', 'inactive'].forEach(function(type) {
+ var $folder = renderFolder(type, items, selected).appendTo($folders);
+ });
+ }
+
+ function renderForm(data, focus) {
+ $form.empty();
+ $typeSelect = Ox.Select({
items: [
{id: 'custom', title: Ox._('Custom')},
{id: 'list', title: Ox._('List')},
@@ -56,78 +168,122 @@ pandora.ui.homeDialog = function() {
{id: 'collection', title: Ox._('Collection')}
],
label: Ox._('Type'),
- labelWidth: 128,
- width: 512
+ labelWidth: 80,
+ value: data.type,
+ width: 240
}).css({
- margin: '4px'
+ margin: '8px'
}).bindEvent({
change: function(data) {
- renderItem({type: data.value})
+ var item = {type: data.value};
+ renderItem(item);
+ renderForm(item, true);
}
}).appendTo($form);
if (data.type == 'custom') {
- var $imageInput = Ox.Input({
+ $imageInput = Ox.Input({
label: Ox._('Image URL'),
- labelWidth: 128,
- width: 512
+ labelWidth: 80,
+ value: data.image || '',
+ width: 240
}).css({
- margin: '4px'
+ margin: '8px'
+ }).bindEvent({
+ change: function(data) {
+ editItem(data.id, 'image', data.value);
+ }
}).appendTo($form);
- var $linkInput = Ox.Input({
+ $linkInput = Ox.Input({
label: Ox._('Link URL'),
- labelWidth: 128,
- width: 512
+ labelWidth: 80,
+ value: data.link || '',
+ width: 240
}).css({
- margin: '4px'
+ margin: '8px'
+ }).bindEvent({
+ change: function(data) {
+ editItem(data.id, 'link', data.value);
+ }
}).appendTo($form);
} else {
- var $nameInput = Ox.Input({
- label: Ox._('List Name'),
- labelWidth: 128,
- width: 512
+ $nameInput = Ox.Input({
+ autocomplete: autocompleteData[data.type],
+ autocompleteSelect: true,
+ autocompleteSelectMaxWidth: 256,
+ label: Ox._('Name'),
+ labelWidth: 80,
+ value: data.contentid || '',
+ width: 240
}).css({
- margin: '4px'
+ margin: '8px'
+ }).bindEvent({
+ change: function(data) {
+ editItem(data.id, 'name', data.value);
+ }
}).appendTo($form);
}
- var $preview = $('
').appendTo($item);
- var $imageContainer = $('
').css({
- background: 'rgb(0, 0, 0)', // FIXME: make themes
- borderRadius: '32px',
- height: '128px',
- width: '128px'
- }).appendTo($preview);
+ if (focus) {
+ (data.type == 'custom' ? $imageInput : $nameInput).focusInput();
+ }
+ }
+
+ function renderItem(data) {
+ $item.empty();
if (data.image) {
- $image = $('
').attr({
+ var $image = $('
').attr({
src: data.image
}).css({
borderRadius: '32px',
+ float: 'left',
height: '128px',
+ margin: '12px',
width: '128px'
- }).appendTo($imageContainer)
+ }).appendTo($item)
+ } else {
+ var $placeholder = $('
').css({
+ border: 'dotted 1px rgb(0, 0, 0)', // FIXME: make themes
+ borderRadius: '32px',
+ height: '128px',
+ margin: '8px',
+ width: '128px'
+ }).appendTo($item);
}
- Ox.EditableContent({
+ var $container = $('
').css({
+ margin: '10px 12px 8px 0'
+ }).appendTo($item);
+ var title = data.title ? (
+ (
+ data.type == 'custom' ? ''
+ : Ox._('Featured ' + Ox.toTitleCase(data.type) + ': ')
+ ) + data.title
+ ) : '';
+ $title = Ox.EditableContent({
+ editable: data.type == 'custom',
placeholder: '' + Ox._('Title') + '',
- value: data.title
- })
- .bindEvent({
+ value: title
+ }).css({
+ fontSize: '13px',
+ fontWeight: 'bold'
+ }).bindEvent({
submit: function(data) {
- editItem('title', data.value);
+ editItem(data.id, 'title', data.value);
}
- }).appendTo($preview);
- Ox.EditableContent({
+ }).appendTo($container);
+ $text = Ox.EditableContent({
+ editable: data.type == 'custom',
placeholder: '' + Ox._('Text') + '',
- value: data.text
- })
- .bindEvent({
+ type: 'textarea',
+ value: data.text || ''
+ }).css({
+ margin: '0 12px 0 0'
+ }).bindEvent({
submit: function(data) {
- editItem('text', data.value);
+ editItem(data.id, 'text', data.value);
}
- }).appendTo($preview);
- return $item;
+ }).appendTo($item);
}
- function renderList(items) {
- console.log('LIST', items)
+ function renderList(items, selected) {
var $list = Ox.TableList({
columns: [
{
@@ -167,13 +323,24 @@ pandora.ui.homeDialog = function() {
],
items: items,
max: 1,
+ selected: [selected],
sort: [{key: 'index', operator: '+'}],
sortable: true,
unique: 'id'
})
.bindEvent({
- select: function() {
-
+ select: function(data) {
+ if (data.ids.length) {
+ var item = Ox.getObjectById(items, data.ids[0])
+ renderItem(item);
+ renderForm(item);
+ }
+ },
+ selectafter: function() {
+ // ...
+ },
+ selectbefore: function() {
+ // ...
}
})
.css({