initial round of text section

This commit is contained in:
j 2013-02-16 01:20:40 +00:00
parent f8ededaf55
commit c8af45e7cf
25 changed files with 2243 additions and 984 deletions

View file

@ -31,6 +31,8 @@
"canEditAnnotations": {"staff": true, "admin": true}, "canEditAnnotations": {"staff": true, "admin": true},
"canEditEvents": {"staff": true, "admin": true}, "canEditEvents": {"staff": true, "admin": true},
"canEditFeaturedLists": {"staff": true, "admin": true}, "canEditFeaturedLists": {"staff": true, "admin": true},
"canEditFeaturedTexts": {"staff": true, "admin": true},
"canEditFeaturedEdits": {"staff": true, "admin": true},
"canEditMetadata": {"staff": true, "admin": true}, "canEditMetadata": {"staff": true, "admin": true},
"canEditPlaces": {"staff": true, "admin": true}, "canEditPlaces": {"staff": true, "admin": true},
"canEditSitePages": {"staff": true, "admin": true}, "canEditSitePages": {"staff": true, "admin": true},
@ -712,6 +714,8 @@
"icons": "posters", "icons": "posters",
"infoIconSize": 256, "infoIconSize": 256,
"item": "", "item": "",
"text": "",
"edit": "",
"itemFind": "", "itemFind": "",
"itemSort": [{"key": "position", "operator": "+"}], "itemSort": [{"key": "position", "operator": "+"}],
"itemView": "info", "itemView": "info",
@ -749,6 +753,11 @@
"featured": true, "featured": true,
"volumes": true "volumes": true
} }
"texts": {
"personal": true,
"favorite": true,
"featured": true
}
}, },
"showSidebar": true, "showSidebar": true,
"showSitePosters": false, "showSitePosters": false,

View file

@ -29,6 +29,8 @@
"canEditAnnotations": {"staff": true, "admin": true}, "canEditAnnotations": {"staff": true, "admin": true},
"canEditEvents": {"staff": true, "admin": true}, "canEditEvents": {"staff": true, "admin": true},
"canEditFeaturedLists": {"staff": true, "admin": true}, "canEditFeaturedLists": {"staff": true, "admin": true},
"canEditFeaturedTexts": {"staff": true, "admin": true},
"canEditFeaturedEdits": {"staff": true, "admin": true},
"canEditMetadata": {"staff": true, "admin": true}, "canEditMetadata": {"staff": true, "admin": true},
"canEditPlaces": {"staff": true, "admin": true}, "canEditPlaces": {"staff": true, "admin": true},
"canEditSitePages": {"staff": true, "admin": true}, "canEditSitePages": {"staff": true, "admin": true},
@ -630,6 +632,8 @@
"icons": "frames", "icons": "frames",
"infoIconSize": 256, "infoIconSize": 256,
"item": "", "item": "",
"text": "",
"edit": "",
"itemFind": "", "itemFind": "",
"itemSort": [{"key": "position", "operator": "+"}], "itemSort": [{"key": "position", "operator": "+"}],
"itemView": "info", "itemView": "info",
@ -670,6 +674,11 @@
"favorite": true, "favorite": true,
"featured": true, "featured": true,
"volumes": true "volumes": true
},
"texts": {
"personal": true,
"favorite": true,
"featured": true
} }
}, },
"showSidebar": true, "showSidebar": true,

View file

@ -29,6 +29,8 @@
"canEditAnnotations": {"staff": true, "admin": true}, "canEditAnnotations": {"staff": true, "admin": true},
"canEditEvents": {"staff": true, "admin": true}, "canEditEvents": {"staff": true, "admin": true},
"canEditFeaturedLists": {"staff": true, "admin": true}, "canEditFeaturedLists": {"staff": true, "admin": true},
"canEditFeaturedTexts": {"staff": true, "admin": true},
"canEditFeaturedEdits": {"staff": true, "admin": true},
"canEditMetadata": {"staff": true, "admin": true}, "canEditMetadata": {"staff": true, "admin": true},
"canEditPlaces": {"staff": true, "admin": true}, "canEditPlaces": {"staff": true, "admin": true},
"canEditSitePages": {"staff": true, "admin": true}, "canEditSitePages": {"staff": true, "admin": true},
@ -549,6 +551,8 @@
"icons": "posters", "icons": "posters",
"infoIconSize": 256, "infoIconSize": 256,
"item": "", "item": "",
"text": "",
"edit": "",
"itemFind": "", "itemFind": "",
"itemSort": [{"key": "position", "operator": "+"}], "itemSort": [{"key": "position", "operator": "+"}],
"itemView": "info", "itemView": "info",
@ -589,6 +593,11 @@
"featured": true, "featured": true,
"volumes": true "volumes": true
} }
"texts": {
"personal": true,
"favorite": true,
"featured": true
}
}, },
"showSidebar": true, "showSidebar": true,
"showSitePosters": false, "showSitePosters": false,

View file

@ -207,7 +207,9 @@ def addList(request):
return { return {
status: {'code': int, 'text': string}, status: {'code': int, 'text': string},
data: { data: {
list: id:
name:
...
} }
} }
''' '''

136
pandora/text/managers.py Normal file
View file

@ -0,0 +1,136 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
from datetime import datetime
from django.db.models import Q, Manager
import models
def parseCondition(condition, user):
'''
'''
k = condition.get('key', 'name')
k = {
'user': 'user__username',
'position': 'position__position',
'posterFrames': 'poster_frames',
}.get(k, k)
if not k:
k = 'name'
v = condition['value']
op = condition.get('operator')
if not op:
op = '='
if op.startswith('!'):
op = op[1:]
exclude = True
else:
exclude = False
if k == 'id':
v = v.split(":")
if len(v) >= 2:
v = (v[0], ":".join(v[1:]))
q = Q(user__username=v[0], name=v[1])
else:
q = Q(id__in=[])
return q
if k == 'subscribed':
key = 'subscribed_users__username'
v = user.username
elif isinstance(v, bool): #featured and public flag
key = k
else:
key = "%s%s" % (k, {
'==': '__iexact',
'^': '__istartswith',
'$': '__iendswith',
}.get(op, '__icontains'))
key = str(key)
if exclude:
q = ~Q(**{key: v})
else:
q = Q(**{key: v})
return q
def parseConditions(conditions, operator, user):
'''
conditions: [
{
value: "war"
}
{
key: "year",
value: "1970-1980,
operator: "!="
},
{
key: "country",
value: "f",
operator: "^"
}
],
operator: "&"
'''
conn = []
for condition in conditions:
if 'conditions' in condition:
q = parseConditions(condition['conditions'],
condition.get('operator', '&'), user)
if q:
conn.append(q)
pass
else:
conn.append(parseCondition(condition, user))
if conn:
q = conn[0]
for c in conn[1:]:
if operator == '|':
q = q | c
else:
q = q & c
return q
return None
class TextManager(Manager):
def get_query_set(self):
return super(TextManager, self).get_query_set()
def find(self, data, user):
'''
query: {
conditions: [
{
value: "war"
}
{
key: "year",
value: "1970-1980,
operator: "!="
},
{
key: "country",
value: "f",
operator: "^"
}
],
operator: "&"
}
'''
#join query with operator
qs = self.get_query_set()
conditions = parseConditions(data['query'].get('conditions', []),
data['query'].get('operator', '&'),
user)
if conditions:
qs = qs.filter(conditions)
if user.is_anonymous():
qs = qs.filter(Q(status='public') | Q(status='featured'))
else:
qs = qs.filter(Q(status='public') | Q(status='featured') | Q(user=user))
return qs

View file

@ -0,0 +1,205 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Deleting model 'Image'
db.delete_table('text_image')
# Deleting model 'Attachment'
db.delete_table('text_attachment')
# Adding model 'Position'
db.create_table('text_position', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('text', self.gf('django.db.models.fields.related.ForeignKey')(related_name='position', to=orm['text.Text'])),
('user', self.gf('django.db.models.fields.related.ForeignKey')(related_name='text_position', to=orm['auth.User'])),
('section', self.gf('django.db.models.fields.CharField')(max_length='255')),
('position', self.gf('django.db.models.fields.IntegerField')(default=0)),
))
db.send_create_signal('text', ['Position'])
# Adding unique constraint on 'Position', fields ['user', 'text', 'section']
db.create_unique('text_position', ['user_id', 'text_id', 'section'])
# Deleting field 'Text.public'
db.delete_column('text_text', 'public')
# Deleting field 'Text.slug'
db.delete_column('text_text', 'slug')
# Deleting field 'Text.title'
db.delete_column('text_text', 'title')
# Deleting field 'Text.published'
db.delete_column('text_text', 'published')
# Adding field 'Text.name'
db.add_column('text_text', 'name',
self.gf('django.db.models.fields.CharField')(default=datetime.datetime(2013, 2, 15, 0, 0), max_length=255),
keep_default=False)
# Adding field 'Text.status'
db.add_column('text_text', 'status',
self.gf('django.db.models.fields.CharField')(default='private', max_length=20),
keep_default=False)
# Adding field 'Text.description'
db.add_column('text_text', 'description',
self.gf('django.db.models.fields.TextField')(default=''),
keep_default=False)
# Adding field 'Text.icon'
db.add_column('text_text', 'icon',
self.gf('django.db.models.fields.files.ImageField')(default='', max_length=100, blank=True),
keep_default=False)
# Adding field 'Text.poster_frames'
db.add_column('text_text', 'poster_frames',
self.gf('ox.django.fields.TupleField')(default=[]),
keep_default=False)
# Adding M2M table for field subscribed_users on 'Text'
db.create_table('text_text_subscribed_users', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('text', models.ForeignKey(orm['text.text'], null=False)),
('user', models.ForeignKey(orm['auth.user'], null=False))
))
db.create_unique('text_text_subscribed_users', ['text_id', 'user_id'])
# Adding unique constraint on 'Text', fields ['user', 'name']
db.create_unique('text_text', ['user_id', 'name'])
def backwards(self, orm):
# Removing unique constraint on 'Text', fields ['user', 'name']
db.delete_unique('text_text', ['user_id', 'name'])
# Removing unique constraint on 'Position', fields ['user', 'text', 'section']
db.delete_unique('text_position', ['user_id', 'text_id', 'section'])
# Adding model 'Image'
db.create_table('text_image', (
('caption', self.gf('django.db.models.fields.CharField')(default='', max_length=255)),
('image', self.gf('django.db.models.fields.files.ImageField')(max_length=100)),
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
))
db.send_create_signal('text', ['Image'])
# Adding model 'Attachment'
db.create_table('text_attachment', (
('caption', self.gf('django.db.models.fields.CharField')(default='', max_length=255)),
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('file', self.gf('django.db.models.fields.files.FileField')(max_length=100)),
))
db.send_create_signal('text', ['Attachment'])
# Deleting model 'Position'
db.delete_table('text_position')
# Adding field 'Text.public'
db.add_column('text_text', 'public',
self.gf('django.db.models.fields.BooleanField')(default=False),
keep_default=False)
# Adding field 'Text.slug'
db.add_column('text_text', 'slug',
self.gf('django.db.models.fields.SlugField')(default='', max_length=50),
keep_default=False)
# Adding field 'Text.title'
db.add_column('text_text', 'title',
self.gf('django.db.models.fields.CharField')(max_length=1000, null=True),
keep_default=False)
# Adding field 'Text.published'
db.add_column('text_text', 'published',
self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now),
keep_default=False)
# Deleting field 'Text.name'
db.delete_column('text_text', 'name')
# Deleting field 'Text.status'
db.delete_column('text_text', 'status')
# Deleting field 'Text.description'
db.delete_column('text_text', 'description')
# Deleting field 'Text.icon'
db.delete_column('text_text', 'icon')
# Deleting field 'Text.poster_frames'
db.delete_column('text_text', 'poster_frames')
# Removing M2M table for field subscribed_users on 'Text'
db.delete_table('text_text_subscribed_users')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '255', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'text.position': {
'Meta': {'unique_together': "(('user', 'text', 'section'),)", 'object_name': 'Position'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'position': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'section': ('django.db.models.fields.CharField', [], {'max_length': "'255'"}),
'text': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'position'", 'to': "orm['text.Text']"}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'text_position'", 'to': "orm['auth.User']"})
},
'text.text': {
'Meta': {'unique_together': "(('user', 'name'),)", 'object_name': 'Text'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'default': "''"}),
'icon': ('django.db.models.fields.files.ImageField', [], {'default': 'None', 'max_length': '100', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'poster_frames': ('ox.django.fields.TupleField', [], {'default': '[]'}),
'status': ('django.db.models.fields.CharField', [], {'default': "'private'", 'max_length': '20'}),
'subscribed_users': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'subscribed_texts'", 'symmetrical': 'False', 'to': "orm['auth.User']"}),
'text': ('django.db.models.fields.TextField', [], {'default': "''"}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'texts'", 'to': "orm['auth.User']"})
}
}
complete_apps = ['text']

View file

@ -0,0 +1,93 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'Text.type'
db.add_column('text_text', 'type',
self.gf('django.db.models.fields.CharField')(default='html', max_length=255),
keep_default=False)
# Adding field 'Text.links'
db.add_column('text_text', 'links',
self.gf('ox.django.fields.DictField')(default={}),
keep_default=False)
def backwards(self, orm):
# Deleting field 'Text.type'
db.delete_column('text_text', 'type')
# Deleting field 'Text.links'
db.delete_column('text_text', 'links')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '255', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'text.position': {
'Meta': {'unique_together': "(('user', 'text', 'section'),)", 'object_name': 'Position'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'position': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'section': ('django.db.models.fields.CharField', [], {'max_length': "'255'"}),
'text': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'position'", 'to': "orm['text.Text']"}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'text_position'", 'to': "orm['auth.User']"})
},
'text.text': {
'Meta': {'unique_together': "(('user', 'name'),)", 'object_name': 'Text'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'default': "''"}),
'icon': ('django.db.models.fields.files.ImageField', [], {'default': 'None', 'max_length': '100', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'links': ('ox.django.fields.DictField', [], {'default': '{}'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'poster_frames': ('ox.django.fields.TupleField', [], {'default': '[]'}),
'status': ('django.db.models.fields.CharField', [], {'default': "'private'", 'max_length': '20'}),
'subscribed_users': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'subscribed_texts'", 'symmetrical': 'False', 'to': "orm['auth.User']"}),
'text': ('django.db.models.fields.TextField', [], {'default': "''"}),
'type': ('django.db.models.fields.CharField', [], {'default': "'html'", 'max_length': '255'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'texts'", 'to': "orm['auth.User']"})
}
}
complete_apps = ['text']

View file

@ -2,40 +2,158 @@
# vi:si:et:sw=4:sts=4:ts=4 # vi:si:et:sw=4:sts=4:ts=4
from __future__ import division, with_statement from __future__ import division, with_statement
from datetime import datetime from datetime import datetime
import os
import subprocess
from glob import glob
from django.db import models from django.db import models
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.conf import settings
import ox
from ox.django.fields import DictField, TupleField
from archive import extract
import managers
class Text(models.Model): class Text(models.Model):
class Meta:
unique_together = ("user", "name")
created = models.DateTimeField(auto_now_add=True) created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True) modified = models.DateTimeField(auto_now=True)
published = models.DateTimeField(default=datetime.now, editable=False) user = models.ForeignKey(User, related_name='texts')
public = models.BooleanField(default=False) name = models.CharField(max_length=255)
status = models.CharField(max_length=20, default='private')
_status = ['private', 'public', 'featured']
type = models.CharField(max_length=255, default='html')
description = models.TextField(default='')
user = models.ForeignKey(User) icon = models.ImageField(default=None, blank=True,
slug = models.SlugField() upload_to=lambda i, x: i.path("icon.jpg"))
title = models.CharField(null=True, max_length=1000)
text = models.TextField(default='') text = models.TextField(default="")
links = DictField(default={}, editable=True)
poster_frames = TupleField(default=[], editable=False)
subscribed_users = models.ManyToManyField(User, related_name='subscribed_texts')
objects = managers.TextManager()
def save(self, *args, **kwargs):
super(Text, self).save(*args, **kwargs)
def __unicode__(self): def __unicode__(self):
return u"%s <%s>" % (self.title, self.slug) return self.get_id()
def get_absolute_url(self): def get_id(self):
return '/text/%s' % self.slug return u'%s:%s' % (self.user.username, self.name)
def accessible(self, user):
return self.user == user or self.status in ('public', 'featured')
class Image(models.Model): def editable(self, user):
image = models.ImageField(upload_to='text/image') if user.is_anonymous():
caption = models.CharField(max_length=255, default="") return False
if self.user == user or \
user.is_staff or \
user.get_profile().capability('canEditFeaturedTexts') == True:
return True
return False
def get_absolute_url(self): def json(self, keys=None, user=None):
return self.image.url if not keys:
keys=['id', 'name', 'user', 'status', 'subscribed', 'posterFrames', 'description', 'text', 'type', 'links']
response = {}
_map = {
'posterFrames': 'poster_frames'
}
for key in keys:
if key == 'id':
response[key] = self.get_id()
elif key == 'user':
response[key] = self.user.username
elif key == 'subscribers':
response[key] = self.subscribed_users.all().count()
elif key == 'subscribed':
if user and not user.is_anonymous():
response[key] = self.subscribed_users.filter(id=user.id).exists()
elif hasattr(self, _map.get(key, key)):
response[key] = getattr(self, _map.get(key,key))
return response
def path(self, name=''):
h = "%07d" % self.id
return os.path.join('texts', h[:2], h[2:4], h[4:6], h[6:], name)
class Attachment(models.Model): def update_icon(self):
file = models.FileField(upload_to='text/attachment') frames = []
caption = models.CharField(max_length=255, default="") if not self.poster_frames:
items = self.get_items(self.user).filter(rendered=True)
if items.count():
poster_frames = []
for i in range(0, items.count(), max(1, int(items.count()/4))):
poster_frames.append({
'item': items[int(i)].itemId,
'position': items[int(i)].poster_frame
})
self.poster_frames = tuple(poster_frames)
self.save()
for i in self.poster_frames:
from item.models import Item
qs = Item.objects.filter(itemId=i['item'])
if qs.count() > 0:
frame = qs[0].frame(i['position'])
if frame:
frames.append(frame)
self.icon.name = self.path('icon.jpg')
icon = self.icon.path
if frames:
while len(frames) < 4:
frames += frames
folder = os.path.dirname(icon)
ox.makedirs(folder)
for f in glob("%s/icon*.jpg" % folder):
os.unlink(f)
cmd = [
settings.LIST_ICON,
'-f', ','.join(frames),
'-o', icon
]
p = subprocess.Popen(cmd)
p.wait()
self.save()
def get_icon(self, size=16):
path = self.path('icon%d.jpg' % size)
path = os.path.join(settings.MEDIA_ROOT, path)
if not os.path.exists(path):
folder = os.path.dirname(path)
ox.makedirs(folder)
if self.icon and os.path.exists(self.icon.path):
source = self.icon.path
max_size = min(self.icon.width, self.icon.height)
else:
source = os.path.join(settings.STATIC_ROOT, 'jpg/list256.jpg')
max_size = 256
if size < max_size:
extract.resize_image(source, path, size=size)
else:
path = source
return path
class Position(models.Model):
class Meta:
unique_together = ("user", "text", "section")
text = models.ForeignKey(Text, related_name='position')
user = models.ForeignKey(User, related_name='text_position')
section = models.CharField(max_length='255')
position = models.IntegerField(default=0)
def __unicode__(self):
return u'%s/%s/%s' % (self.section, self.position, self.text)
def get_absolute_url(self):
return self.file.url

View file

@ -1,27 +1,96 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4 # vi:si:et:sw=4:sts=4:ts=4
from __future__ import division from __future__ import division
import os
import re
import ox
from ox.utils import json 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 ox.django.api import actions from ox.django.api import actions
from ox.django.decorators import login_required_json
from ox.django.http import HttpFileResponse
from ox.django.shortcuts import render_to_json_response, get_object_or_404_json, json_response
from django.db.models import Count, Q, Sum, Max
from item import utils
import models
def get_text_or_404_json(id):
id = id.split(':')
username = id[0]
textname = ":".join(id[1:])
return get_object_or_404_json(models.Text, user__username=username, name=textname)
@login_required_json
def addText(request):
'''
param data {
name: value,
}
return {
status: {'code': int, 'text': string},
data: {
id:
name:
...
}
}
'''
data = json.loads(request.POST['data'])
data['name'] = re.sub(' \[\d+\]$', '', data['name']).strip()
name = data['name']
if not name:
name = "Untitled"
num = 1
created = False
while not created:
text, created = models.Text.objects.get_or_create(name=name, user=request.user)
num += 1
name = data['name'] + ' [%d]' % num
text.save()
if text.status == 'featured':
pos, created = models.Position.objects.get_or_create(text=text,
user=request.user, section='featured')
qs = models.Position.objects.filter(section='featured')
else:
pos, created = models.Position.objects.get_or_create(text=text,
user=request.user, section='personal')
qs = models.Position.objects.filter(user=request.user, section='personal')
pos.position = qs.aggregate(Max('position'))['position__max'] + 1
pos.save()
response = json_response(status=200, text='created')
response['data'] = text.json()
return render_to_json_response(response)
actions.register(addText, cache=False)
def getText(request): def getText(request):
''' '''
param data param data {
string id id: textid
}
return page return {
id:
text:
...
}
''' '''
response = json_response({}) response = json_response()
itemId = json.loads(request.POST['data']) data = json.loads(request.POST['data'])
item = get_object_or_404_json(models.Text, pk=itemId) public_id = data['id']
response['data']['page'] = item.html() if public_id == '':
qs = models.Text.objects.filter(name='')
if qs.count() == 0:
text = models.Text()
text.name = ''
text.text = 'Please put something here'
text.user = request.user
text.save()
else:
text = qs[0]
else:
text = get_text_or_404_json(data['id'])
response['data'] = text.json()
return render_to_json_response(response) return render_to_json_response(response)
actions.register(getText) actions.register(getText)
@ -29,22 +98,355 @@ actions.register(getText)
@login_required_json @login_required_json
def editText(request): def editText(request):
''' '''
param data param data {
string id id:
text:
return page public: boolean
}
return {
id:
text:
...
}
''' '''
response = json_response({}) response = json_response()
itemId = json.loads(request.POST['data']) data = json.loads(request.POST['data'])
item = get_object_or_404_json(models.Text, pk=itemId) if data['id']:
response['data']['page'] = item.html() public_id = data['id'].split(':')
username = public_id[0]
name = ":".join(public_id[1:])
text, created = models.Text.objects.get_or_create(name=name, user=models.User.objects.get(username=username))
if created:
text.user = request.user
else:
qs = models.Text.objects.filter(name='')
if qs.count() == 0:
if request.user.get_profile().capability('canEditFeaturedTexts'):
text = models.Text(name='', user=request.user)
text.save()
else:
response = json_response(status=403, text='permission denied')
return render_to_json_response(response)
else:
text = qs[0]
if text.editable(request.user):
for key in data:
if key == 'status':
value = data[key]
if value not in text._status:
value = text._status[0]
if value == 'private':
for user in text.subscribed_users.all():
text.subscribed_users.remove(user)
qs = models.Position.objects.filter(user=request.user,
section='section', text=text)
if qs.count() > 1:
pos = qs[0]
pos.section = 'personal'
pos.save()
elif value == 'featured':
if request.user.get_profile().capability('canEditFeaturedTexts'):
pos, created = models.Position.objects.get_or_create(text=text, user=request.user,
section='featured')
if created:
qs = models.Position.objects.filter(user=request.user, section='featured')
pos.position = qs.aggregate(Max('position'))['position__max'] + 1
pos.save()
models.Position.objects.filter(text=text).exclude(id=pos.id).delete()
else:
value = text.status
elif text.status == 'featured' and value == 'public':
models.Position.objects.filter(text=text).delete()
pos, created = models.Position.objects.get_or_create(text=text,
user=text.user,section='personal')
qs = models.Position.objects.filter(user=text.user,
section='personal')
pos.position = qs.aggregate(Max('position'))['position__max'] + 1
pos.save()
for u in text.subscribed_users.all():
pos, created = models.Position.objects.get_or_create(text=text, user=u,
section='public')
qs = models.Position.objects.filter(user=u, section='public')
pos.position = qs.aggregate(Max('position'))['position__max'] + 1
pos.save()
text.status = value
elif key == 'name':
data['name'] = re.sub(' \[\d+\]$', '', data['name']).strip()
name = data['name']
if not name:
name = "Untitled"
num = 1
while models.Text.objects.filter(name=name, user=text.user).exclude(id=text.id).count()>0:
num += 1
name = data['name'] + ' [%d]' % num
text.name = name
elif key == 'description':
text.description = ox.sanitize_html(data['description'])
elif key == 'text':
text.text = ox.sanitize_html(data['text'])
if 'position' in data:
pos, created = models.Position.objects.get_or_create(text=text, user=request.user)
pos.position = data['position']
pos.section = 'featured'
if text.status == 'private':
pos.section = 'personal'
pos.save()
if 'type' in data:
if data['type'] == 'pdf':
text.type = 'pdf'
else:
text.type = 'html'
if 'posterFrames' in data:
text.poster_frames = tuple(data['posterFrames'])
text.update_icon()
text.save()
response['data'] = text.json(user=request.user)
else:
response = json_response(status=403, text='permission denied')
return render_to_json_response(response) return render_to_json_response(response)
actions.register(editText, cache=False) actions.register(editText, cache=False)
def findText(request): def _order_query(qs, sort):
order_by = []
for e in sort:
operator = e['operator']
if operator != '-':
operator = ''
key = {
'subscribed': 'subscribed_users',
'items': 'numberofitems'
}.get(e['key'], e['key'])
order = '%s%s' % (operator, key)
order_by.append(order)
if key == 'subscribers':
qs = qs.annotate(subscribers=Sum('subscribed_users'))
if order_by:
qs = qs.order_by(*order_by)
qs = qs.distinct()
return qs
def parse_query(data, user):
query = {}
query['range'] = [0, 100]
query['sort'] = [{'key':'user', 'operator':'+'}, {'key':'name', 'operator':'+'}]
for key in ('keys', 'group', 'text', 'range', 'position', 'positions', 'sort'):
if key in data:
query[key] = data[key]
print data
query['qs'] = models.Text.objects.find(data, user).exclude(name='')
print query
return query
def findTexts(request):
''' '''
param data {
query: {
conditions: [
{
key: 'user',
value: 'something',
operator: '='
}
]
operator: ","
},
sort: [{key: 'name', operator: '+'}],
range: [0, 100]
keys: []
}
possible query keys:
name, user, featured, subscribed
possible keys:
name, user, featured, subscribed, query
}
return {status: {code: int, text: string},
data: {
items: [
{name:, user:, featured:, public...}
]
}
}
''' '''
response = json_response({}) data = json.loads(request.POST['data'])
query = parse_query(data, request.user)
#order
is_section_request = query['sort'] == [{u'operator': u'+', u'key': u'position'}]
def is_featured_condition(x):
return x['key'] == 'status' and \
x['value'] == 'featured' and \
x['operator'] in ('=', '==')
is_featured = len(filter(is_featured_condition, data['query'].get('conditions', []))) > 0
if is_section_request:
qs = query['qs']
if not is_featured and 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'])
response = json_response()
if 'keys' in data:
qs = qs[query['range'][0]:query['range'][1]]
response['data']['items'] = [l.json(data['keys'], request.user) for l in qs]
elif 'position' in data:
#FIXME: actually implement position requests
response['data']['position'] = 0
elif 'positions' in data:
ids = [i.get_id() for i in qs]
response['data']['positions'] = utils.get_positions(ids, query['positions'])
else:
response['data']['items'] = qs.count()
return render_to_json_response(response) return render_to_json_response(response)
actions.register(findText) actions.register(findTexts)
@login_required_json
def removeText(request):
'''
param data {
id: testId,
}
return {
status: {'code': int, 'text': string},
data: {
}
}
'''
data = json.loads(request.POST['data'])
text = get_text_or_404_json(data['id'])
response = json_response()
if text.editable(request.user):
text.delete()
else:
response = json_response(status=403, text='not allowed')
return render_to_json_response(response)
actions.register(removeText, cache=False)
@login_required_json
def subscribeToText(request):
'''
param data {
id: testId,
}
return {
status: {'code': int, 'text': string},
data: {
}
}
'''
data = json.loads(request.POST['data'])
text = get_text_or_404_json(data['id'])
user = request.user
if text.status == 'public' and \
text.subscribed_users.filter(username=user.username).count() == 0:
text.subscribed_users.add(user)
pos, created = models.Position.objects.get_or_create(text=text, user=user, section='public')
if created:
qs = models.Position.objects.filter(user=user, section='public')
pos.position = qs.aggregate(Max('position'))['position__max'] + 1
pos.save()
response = json_response()
return render_to_json_response(response)
actions.register(subscribeToText, cache=False)
@login_required_json
def unsubscribeFromText(request):
'''
param data {
id: testId,
user: username(only admins)
}
return {
status: {'code': int, 'text': string},
data: {
}
}
'''
data = json.loads(request.POST['data'])
text = get_text_or_404_json(data['id'])
user = request.user
text.subscribed_users.remove(user)
models.Position.objects.filter(text=text, user=user, section='public').delete()
response = json_response()
return render_to_json_response(response)
actions.register(unsubscribeFromText, cache=False)
@login_required_json
def sortTexts(request):
'''
param data {
section: 'personal',
ids: [1,2,4,3]
}
known sections: 'personal', 'public', 'featured'
featured can only be edited by admins
return {
status: {'code': int, 'text': string},
data: {
}
}
'''
data = json.loads(request.POST['data'])
position = 0
section = data['section']
#ids = list(set(data['ids']))
ids = data['ids']
if section == 'featured' and not request.user.get_profile().capability('canEditFeaturedTexts'):
response = json_response(status=403, text='not allowed')
else:
user = request.user
if section == 'featured':
for i in ids:
l = get_text_or_404_json(i)
qs = models.Position.objects.filter(section=section, text=l)
if qs.count() > 0:
pos = qs[0]
else:
pos = models.Position(text=l, user=user, section=section)
if pos.position != position:
pos.position = position
pos.save()
position += 1
models.Position.objects.filter(section=section, text=l).exclude(id=pos.id).delete()
else:
for i in ids:
l = get_text_or_404_json(i)
pos, created = models.Position.objects.get_or_create(text=l,
user=request.user, section=section)
if pos.position != position:
pos.position = position
pos.save()
position += 1
response = json_response()
return render_to_json_response(response)
actions.register(sortTexts, cache=False)
def icon(request, id, size=16):
if not size:
size = 16
id = id.split(':')
username = id[0]
textname = ":".join(id[1:])
qs = models.Text.objects.filter(user__username=username, name=textname)
if qs.count() == 1 and qs[0].accessible(request.user):
text = qs[0]
icon = text.get_icon(int(size))
else:
icon = os.path.join(settings.STATIC_ROOT, 'jpg/list256.jpg')
return HttpFileResponse(icon, content_type='image/jpeg')

View file

@ -28,6 +28,7 @@ urlpatterns = patterns('',
(r'^api/?$', include(ox.django.api.urls)), (r'^api/?$', include(ox.django.api.urls)),
(r'^resetUI$', 'user.views.reset_ui'), (r'^resetUI$', 'user.views.reset_ui'),
(r'^list/(?P<id>.*?)/icon(?P<size>\d*).jpg$', 'itemlist.views.icon'), (r'^list/(?P<id>.*?)/icon(?P<size>\d*).jpg$', 'itemlist.views.icon'),
(r'^text/(?P<id>.*?)/icon(?P<size>\d*).jpg$', 'text.views.icon'),
(r'^robots.txt$', serve_static_file, {'location': os.path.join(settings.STATIC_ROOT, 'robots.txt'), 'content_type': 'text/plain'}), (r'^robots.txt$', serve_static_file, {'location': os.path.join(settings.STATIC_ROOT, 'robots.txt'), 'content_type': 'text/plain'}),
(r'^favicon.ico$', serve_static_file, {'location': os.path.join(settings.STATIC_ROOT, 'png/icon.16.png'), 'content_type': 'image/x-icon'}), (r'^favicon.ico$', serve_static_file, {'location': os.path.join(settings.STATIC_ROOT, 'png/icon.16.png'), 'content_type': 'image/x-icon'}),
(r'^opensearch.xml$', 'app.views.opensearch_xml'), (r'^opensearch.xml$', 'app.views.opensearch_xml'),

View file

@ -14,6 +14,7 @@ from ox.django.fields import DictField
from ox.utils import json from ox.utils import json
from itemlist.models import List, Position from itemlist.models import List, Position
import text
import managers import managers
import tasks import tasks
@ -262,6 +263,29 @@ def get_ui(user_ui, user=None):
ids.append(id) ids.append(id)
return ids return ids
def add_texts(texts, section):
P = text.models.Position
ids = []
for t in texts:
qs = P.objects.filter(section=section)
if section == 'featured':
try:
pos = P.objects.get(text=t, section=section)
created = False
except P.DoesNotExist:
pos = P(text=t, section=section, user=l.user)
pos.save()
created = True
else:
pos, created = P.objects.get_or_create(text=t, user=user, section=section)
qs = qs.filter(user=user)
if created:
pos.position = qs.aggregate(Max('position'))['position__max'] + 1
pos.save()
ids.append(t.get_id())
return ids
ids = [''] ids = ['']
if user: if user:
ids += add(user.lists.exclude(status="featured"), 'personal') ids += add(user.lists.exclude(status="featured"), 'personal')
@ -270,6 +294,11 @@ def get_ui(user_ui, user=None):
for i in ui['lists'].keys(): for i in ui['lists'].keys():
if i not in ids: if i not in ids:
del ui['lists'][i] del ui['lists'][i]
tids = ['']
if user:
tids += add_texts(user.texts.exclude(status="featured"), 'personal')
tids += add_texts(user.subscribed_texts.filter(status='public'), 'public')
tids += add_texts(text.models.Text.objects.filter(status='featured'), 'featured')
return ui return ui
def init_user(user, request=None): def init_user(user, request=None):

View file

@ -54,7 +54,10 @@ pandora.UI = (function() {
self.previousUI = Ox.clone(pandora.user.ui, true); self.previousUI = Ox.clone(pandora.user.ui, true);
self.previousUI._list = pandora.getListState(self.previousUI.find); self.previousUI._list = pandora.getListState(self.previousUI.find);
if (args.section == 'texts') {
trigger['section'] = args['section'];
trigger['text'] = args['text'];
} else {
if ('find' in args) { if ('find' in args) {
// the challenge here is that find may change list, // the challenge here is that find may change list,
// and list may then change listSort and listView, // and list may then change listSort and listView,
@ -152,6 +155,7 @@ pandora.UI = (function() {
add['videoPoints.' + item] = {annotation: '', 'in': 0, out: 0, position: 0}; add['videoPoints.' + item] = {annotation: '', 'in': 0, out: 0, position: 0};
} }
} }
}
// items in args trigger events, items in add do not // items in args trigger events, items in add do not
[args, add].forEach(function(obj, isAdd) { [args, add].forEach(function(obj, isAdd) {

View file

@ -16,10 +16,10 @@ pandora.URL = (function() {
var state = {}; var state = {};
state.type = pandora.site.itemsSection; state.type = pandora.user.ui.section == 'items' ? pandora.site.itemsSection : pandora.user.ui.section;
state.item = pandora.user.ui[pandora.user.ui.section.slice(0, -1)];
state.item = pandora.user.ui.item;
if(pandora.user.ui.section == 'items') {
if (!pandora.user.ui.item) { if (!pandora.user.ui.item) {
state.view = pandora.user.ui.listView; state.view = pandora.user.ui.listView;
state.sort = pandora.user.ui.listSort; state.sort = pandora.user.ui.listSort;
@ -28,6 +28,7 @@ pandora.URL = (function() {
state.view = pandora.user.ui.itemView; state.view = pandora.user.ui.itemView;
state.sort = pandora.user.ui.itemSort; state.sort = pandora.user.ui.itemSort;
} }
}
if (state.view == 'map') { if (state.view == 'map') {
state.span = pandora.user.ui.mapFind state.span = pandora.user.ui.mapFind
@ -79,10 +80,11 @@ pandora.URL = (function() {
var set = { var set = {
section: state.type == pandora.site.itemsSection ? 'items' : state.type, section: state.type == pandora.site.itemsSection ? 'items' : state.type,
item: state.item,
page: '' page: ''
}; };
set[set.section.slice(0, -1)] = state.item;
if (set.section == 'items') {
if (state.view) { if (state.view) {
set[!state.item ? 'listView' : 'itemView'] = state.view; set[!state.item ? 'listView' : 'itemView'] = state.view;
} }
@ -131,6 +133,7 @@ pandora.URL = (function() {
set.find = pandora.site.user.ui.find; set.find = pandora.site.user.ui.find;
} }
} }
}
if (state.hash && state.hash.query) { if (state.hash && state.hash.query) {
state.hash.query.forEach(function(kv) { state.hash.query.forEach(function(kv) {
@ -246,6 +249,19 @@ pandora.URL = (function() {
calendar: 'date' calendar: 'date'
} }
}; };
//Text
views['texts'] = {
list: [],
item: ['text']
}
spanType['texts'] = {
list: [],
item: {}
}
sortKeys['texts'] = {
list: {},
item: {}
}
findKeys = [{id: 'list', type: 'string'}].concat(pandora.site.itemKeys); findKeys = [{id: 'list', type: 'string'}].concat(pandora.site.itemKeys);

View file

@ -12,7 +12,11 @@ pandora.ui.allItems = function() {
.on({ .on({
click: function() { click: function() {
that.gainFocus(); that.gainFocus();
if (pandora.user.ui.section == 'items') {
pandora.user.ui._list && pandora.UI.set('find', {conditions: [], operator: '&'}); pandora.user.ui._list && pandora.UI.set('find', {conditions: [], operator: '&'});
} else {
pandora.UI.set(pandora.user.ui.section.slice(0, -1), '');
}
} }
}) })
.bindEvent({ .bindEvent({
@ -33,9 +37,12 @@ pandora.ui.allItems = function() {
overflow: 'hidden', overflow: 'hidden',
whiteSpace: 'nowrap' whiteSpace: 'nowrap'
}) })
.html('All ' + pandora.site.itemName.plural) .html(pandora.user.ui.section == 'items' ? 'All ' + pandora.site.itemName.plural
.appendTo(that), : pandora.site.site.name + ' ' + Ox.toTitleCase(pandora.user.ui.section))
$items = $('<div>') .appendTo(that);
if (pandora.user.ui.section == 'items') {
var $items = $('<div>')
.css({ .css({
float: 'left', float: 'left',
width: '42px', width: '42px',
@ -56,12 +63,12 @@ pandora.ui.allItems = function() {
type: 'image' type: 'image'
}) })
.appendTo(that); .appendTo(that);
pandora.api.find({ pandora.api.find({
query: {conditions: [], operator: '&'} query: {conditions: [], operator: '&'}
}, function(result) { }, function(result) {
that.update(result.data.items); that.update(result.data.items);
}); });
}
that.update = function(items) { that.update = function(items) {
$items.html(Ox.formatNumber(items)); $items.html(Ox.formatNumber(items));

View file

@ -3,6 +3,9 @@
'use strict'; 'use strict';
pandora.ui.deleteListDialog = function(list) { pandora.ui.deleteListDialog = function(list) {
var ui = pandora.user.ui,
folderItems = ui.section == 'items' ? 'Lists' : Ox.toTitleCase(ui.section),
folderItem = folderItems.slice(0, -1);
var listData = pandora.getListData(list), var listData = pandora.getListData(list),
$folderList = pandora.$ui.folderList[listData.folder], $folderList = pandora.$ui.folderList[listData.folder],
@ -10,7 +13,7 @@ pandora.ui.deleteListDialog = function(list) {
buttons: [ buttons: [
Ox.Button({ Ox.Button({
id: 'keep', id: 'keep',
title: 'Keep List' title: 'Keep ' + folderItem
}).bindEvent({ }).bindEvent({
click: function() { click: function() {
that.close(); that.close();
@ -18,23 +21,27 @@ pandora.ui.deleteListDialog = function(list) {
}), }),
Ox.Button({ Ox.Button({
id: 'delete', id: 'delete',
title: 'Delete List' title: 'Delete ' + folderItem
}).bindEvent({ }).bindEvent({
click: function() { click: function() {
that.close(); that.close();
pandora.api.removeList({ pandora.api['remove' + folderItem]({
id: listData.id id: listData.id
}, function(result) { }, function(result) {
Ox.Request.clearCache('findLists'); Ox.Request.clearCache('find' + folderItems);
Ox.Request.clearCache(listData.id); Ox.Request.clearCache(listData.id);
$folderList $folderList
.options({selected: []}) .options({selected: []})
.bindEventOnce({ .bindEventOnce({
load: function() { load: function() {
if (ui.section == 'items') {
pandora.UI.set('lists.' + listData.id, null); pandora.UI.set('lists.' + listData.id, null);
pandora.UI.set({ pandora.UI.set({
find: pandora.site.user.ui.find find: pandora.site.user.ui.find
}); });
} else {
pandora.UI.set(folderItem.toLowerCase(), '');
}
} }
}) })
.reloadList(); .reloadList();
@ -51,7 +58,7 @@ pandora.ui.deleteListDialog = function(list) {
.append( .append(
$('<div>') $('<div>')
.css({position: 'absolute', left: '96px', top: '16px', width: '192px'}) .css({position: 'absolute', left: '96px', top: '16px', width: '192px'})
.html('Are you sure you want to delete the list "' + listData.name + '"?') .html('Are you sure you want to delete the ' + folderItem.toLowerCase() + ' "' + listData.name + '"?')
), ),
height: 128, height: 128,
keys: {enter: 'delete', escape: 'keep'}, keys: {enter: 'delete', escape: 'keep'},

View file

@ -1,7 +1,10 @@
// vim: et:ts=4:sw=4:sts=4:ft=javascript // vim: et:ts=4:sw=4:sts=4:ft=javascript
'use strict'; 'use strict';
pandora.ui.folderBrowserBar = function(id) { pandora.ui.folderBrowserBar = function(id) {
var that = Ox.Bar({ var ui = pandora.user.ui,
folderItems = ui.section == 'items' ? 'Lists' : Ox.toTitleCase(ui.section),
folderItem = folderItems.slice(0, -1),
that = Ox.Bar({
size: 24 size: 24
}); });
pandora.$ui.findListElement[id] = Ox.FormElementGroup({ pandora.$ui.findListElement[id] = Ox.FormElementGroup({
@ -9,7 +12,7 @@ pandora.ui.folderBrowserBar = function(id) {
pandora.$ui.findListSelect[id] = Ox.Select({ pandora.$ui.findListSelect[id] = Ox.Select({
items: [ items: [
{id: 'user', title: 'Find: User'}, {id: 'user', title: 'Find: User'},
{id: 'name', title: 'Find: List'} {id: 'name', title: 'Find: ' + folderItem}
], ],
overlap: 'right', overlap: 'right',
type: 'image' type: 'image'
@ -56,7 +59,7 @@ pandora.ui.folderBrowserBar = function(id) {
{key: 'status', value: 'private', operator: '!='}, {key: 'status', value: 'private', operator: '!='},
{key: key, value: value, operator: '='} {key: key, value: value, operator: '='}
], operator: '&'}; ], operator: '&'};
return pandora.api.findLists(Ox.extend(data, { return pandora.api['find' + folderItems](Ox.extend(data, {
query: query query: query
}), callback); }), callback);
} }

View file

@ -3,8 +3,11 @@
pandora.ui.folderBrowserList = function(id) { pandora.ui.folderBrowserList = function(id) {
// fixme: user and name are set to the same width here, // fixme: user and name are set to the same width here,
// but resizeFolders will set them to different widths // but resizeFolders will set them to different widths
var columnWidth = (pandora.user.ui.sidebarSize - Ox.UI.SCROLLBAR_SIZE - 96) / 2, var ui = pandora.user.ui,
i = Ox.getIndexById(pandora.site.sectionFolders[pandora.user.ui.section], id), columnWidth = (ui.sidebarSize - Ox.UI.SCROLLBAR_SIZE - (ui.section == 'items' ? 96 : 32)) / 2,
i = Ox.getIndexById(pandora.site.sectionFolders[ui.section], id),
folderItems = ui.section == 'items' ? 'Lists' : Ox.toTitleCase(ui.section),
folderItem = folderItems.slice(0, -1),
that = Ox.TableList({ that = Ox.TableList({
columns: [ columns: [
{ {
@ -52,7 +55,7 @@ pandora.ui.folderBrowserList = function(id) {
}, },
id: 'name', id: 'name',
operator: '+', operator: '+',
title: 'List', title: folderItem,
visible: true, visible: true,
width: Math.ceil(columnWidth) width: Math.ceil(columnWidth)
}, },
@ -62,7 +65,7 @@ pandora.ui.folderBrowserList = function(id) {
format: {type: 'number'}, format: {type: 'number'},
operator: '-', operator: '-',
title: 'Items', title: 'Items',
visible: true, visible: ui.section == 'items',
width: 48 width: 48
}, },
{ {
@ -72,7 +75,7 @@ pandora.ui.folderBrowserList = function(id) {
format: function(value, data) { format: function(value, data) {
return $('<img>') return $('<img>')
.attr({ .attr({
src: Ox.UI.getImageURL(value == 'static' ? 'symbolClick' : 'symbolFind') src: Ox.UI.getImageURL(value == 'smart' ? 'symbolFind' : value == 'pdf' ? 'symbolFiles' : value == 'html' ? 'symbolFile' : 'symbolClick')
}) })
.css({ .css({
width: '10px', width: '10px',
@ -89,7 +92,7 @@ pandora.ui.folderBrowserList = function(id) {
? (data.user == pandora.user.username ? 'Edit Query' : 'Show Query') ? (data.user == pandora.user.username ? 'Edit Query' : 'Show Query')
: (data.user == pandora.user.username ? 'Edit Default View' : 'Default View: ...'); : (data.user == pandora.user.username ? 'Edit Default View' : 'Default View: ...');
}, },
visible: true, visible: ui.section == 'items',
width: 16 width: 16
}, },
{ {
@ -116,7 +119,7 @@ pandora.ui.folderBrowserList = function(id) {
tooltip: function(data) { tooltip: function(data) {
var checked = id == 'favorite' ? data.subscribed : data.status == 'featured'; var checked = id == 'favorite' ? data.subscribed : data.status == 'featured';
return (checked ? 'Remove from' : 'Add to') return (checked ? 'Remove from' : 'Add to')
+ ' ' + Ox.toTitleCase(id) + ' Lists'; + ' ' + Ox.toTitleCase(id) + ' ' + folderItems;
}, },
visible: true, visible: true,
width: 16 width: 16
@ -130,7 +133,7 @@ pandora.ui.folderBrowserList = function(id) {
], operator: '&'} : {conditions: [ ], operator: '&'} : {conditions: [
{key: 'status', value: 'private', operator: '!='} {key: 'status', value: 'private', operator: '!='}
], operator: ''}; ], operator: ''};
return pandora.api.findLists(Ox.extend(data, { return pandora.api['find' + folderItems](Ox.extend(data, {
query: query query: query
}), callback); }), callback);
}, },
@ -139,7 +142,7 @@ pandora.ui.folderBrowserList = function(id) {
// not-featured list may be in the user's favorites folder // not-featured list may be in the user's favorites folder
keys: id == 'featured' ? ['subscribed'] : [], keys: id == 'featured' ? ['subscribed'] : [],
pageLength: 1000, pageLength: 1000,
selected: pandora.getListData().folder == id ? [pandora.user.ui._list] : [], selected: pandora.getListData().folder == id ? [ui.section == 'items' ? ui._list : ui[ui.section.slice(0, -1)]] : [],
sort: [{key: 'name', operator: '+'}], sort: [{key: 'name', operator: '+'}],
unique: 'id' unique: 'id'
}) })
@ -153,19 +156,19 @@ pandora.ui.folderBrowserList = function(id) {
*/ */
} else if (data.key == 'subscribed') { } else if (data.key == 'subscribed') {
var subscribed = that.value(data.id, 'subscribed'); var subscribed = that.value(data.id, 'subscribed');
pandora.api[subscribed ? 'unsubscribeFromList' : 'subscribeToList']({ pandora.api[subscribed ? 'unsubscribeFrom' + folderItem : 'subscribeTo' + folderItem]({
id: data.id id: data.id
}, function(result) { }, function(result) {
that.value(data.id, 'subscribed', !subscribed); that.value(data.id, 'subscribed', !subscribed);
}); });
} else if (data.key == 'status') { } else if (data.key == 'status') {
pandora.api.editList({ pandora.api['edit' + folderItem]({
id: data.id, id: data.id,
status: that.value(data.id, 'status') == 'featured' ? 'public' : 'featured' status: that.value(data.id, 'status') == 'featured' ? 'public' : 'featured'
}, function(result) { }, function(result) {
Ox.Log('', 'result', result) Ox.Log('', 'result', result)
if (result.data.user == pandora.user.username || result.data.subscribed) { if (result.data.user == pandora.user.username || result.data.subscribed) {
Ox.Request.clearCache(); // fixme: remove Ox.Request.clearCache(); // fixme: removen
pandora.$ui.folderList[ pandora.$ui.folderList[
result.data.user == pandora.user.username ? 'personal' : 'favorite' result.data.user == pandora.user.username ? 'personal' : 'favorite'
].reloadList(); ].reloadList();
@ -175,7 +178,7 @@ pandora.ui.folderBrowserList = function(id) {
} }
}, },
init: function(data) { init: function(data) {
pandora.site.sectionFolders[pandora.user.ui.section][i].items = data.items; pandora.site.sectionFolders[ui.section][i].items = data.items;
pandora.$ui.folder[i].$content.css({ pandora.$ui.folder[i].$content.css({
height: 40 + data.items * 16 + 'px' height: 40 + data.items * 16 + 'px'
}); });
@ -185,7 +188,9 @@ pandora.ui.folderBrowserList = function(id) {
pandora.resizeFolders(); pandora.resizeFolders();
}, },
paste: function(data) { paste: function(data) {
if (ui.section == 'items') {
pandora.$ui.list.triggerEvent('paste', data); pandora.$ui.list.triggerEvent('paste', data);
}
}, },
select: function(data) { select: function(data) {
// fixme: duplicated // fixme: duplicated
@ -195,6 +200,7 @@ pandora.ui.folderBrowserList = function(id) {
id != id_ && $list.options('selected', []); id != id_ && $list.options('selected', []);
}); });
} }
if (ui.section == 'items') {
pandora.UI.set({ pandora.UI.set({
find: { find: {
conditions: list ? [ conditions: list ? [
@ -203,6 +209,9 @@ pandora.ui.folderBrowserList = function(id) {
operator: '&' operator: '&'
} }
}); });
} else {
pandora.UI.set(ui.section.slice(0, -1), list);
}
} }
}); });
return that; return that;

View file

@ -1,20 +1,23 @@
// vim: et:ts=4:sw=4:sts=4:ft=javascript // vim: et:ts=4:sw=4:sts=4:ft=javascript
'use strict'; 'use strict';
pandora.ui.folderList = function(id) { pandora.ui.folderList = function(id) {
var i = Ox.getIndexById(pandora.site.sectionFolders[pandora.user.ui.section], id), var ui = pandora.user.ui,
canEditFeaturedLists = pandora.site.capabilities.canEditFeaturedLists[pandora.user.level], i = Ox.getIndexById(pandora.site.sectionFolders[ui.section], id),
folderItems = ui.section == 'items' ? 'Lists' : Ox.toTitleCase(ui.section),
folderItem = folderItems.slice(0, -1),
canEditFeatured = pandora.site.capabilities['canEditFeatured' + folderItems][pandora.user.level],
that; that;
if (pandora.user.ui.section == 'items') {
var columns, items; var columns, items;
if (id != 'volumes') { if (id != 'volumes') {
columns = [ columns = [
{ {
clickable: function(data) { clickable: function(data) {
return data.user == pandora.user.username || (id == 'featured' && canEditFeaturedLists); return data.user == pandora.user.username || (id == 'featured' && canEditFeatured);
}, },
format: function(value, data) { format: function(value, data) {
return $('<img>').attr({ return $('<img>').attr({
src: '/list/' + data.id + '/icon.jpg' src: '/' + folderItem.toLowerCase() + '/' + data.id + '/icon.jpg'
}).css({ }).css({
width: '14px', width: '14px',
height: '14px', height: '14px',
@ -26,7 +29,7 @@ pandora.ui.folderList = function(id) {
operator: '+', operator: '+',
tooltip: function(data) { tooltip: function(data) {
return data.user == pandora.user.username return data.user == pandora.user.username
|| (id == 'featured' && canEditFeaturedLists) || (id == 'featured' && canEditFeatured)
? 'Edit Icon' ? 'Edit Icon'
: ''; : '';
}, },
@ -42,7 +45,7 @@ pandora.ui.folderList = function(id) {
visible: id == 'favorite', visible: id == 'favorite',
// fixme: user and name are set to the same width here, // fixme: user and name are set to the same width here,
// but resizeFolders will set them to different widths // but resizeFolders will set them to different widths
width: pandora.user.ui.sidebarWidth - 96 width: ui.sidebarWidth - 96
}, },
{ {
editable: function(data) { editable: function(data) {
@ -61,7 +64,7 @@ pandora.ui.folderList = function(id) {
return Ox.decodeHTMLEntities(value); return Ox.decodeHTMLEntities(value);
}, },
visible: id != 'favorite', visible: id != 'favorite',
width: pandora.user.ui.sidebarWidth - 96 width: ui.sidebarWidth - 96
}, },
{ {
align: 'right', align: 'right',
@ -78,7 +81,7 @@ pandora.ui.folderList = function(id) {
format: function(value, data) { format: function(value, data) {
return $('<img>') return $('<img>')
.attr({ .attr({
src: Ox.UI.getImageURL(value == 'static' ? 'symbolClick' : 'symbolFind') src: Ox.UI.getImageURL(value == 'smart' ? 'symbolFind' : value == 'pdf' ? 'symbolFiles' : value == 'html' ? 'symbolFile' : 'symbolClick')
}) })
.css({ .css({
width: '10px', width: '10px',
@ -140,7 +143,7 @@ pandora.ui.folderList = function(id) {
{key: 'status', value: 'featured', operator: '='} // fixme: '==' performs better {key: 'status', value: 'featured', operator: '='} // fixme: '==' performs better
], operator: '&'}; ], operator: '&'};
} }
return pandora.api.findLists(Ox.extend(data, { return pandora.api['find' + folderItems](Ox.extend(data, {
query: query query: query
}), callback); }), callback);
}; };
@ -167,7 +170,7 @@ pandora.ui.folderList = function(id) {
operator: '+', operator: '+',
tooltip: 'Edit Title', tooltip: 'Edit Title',
visible: true, visible: true,
width: pandora.user.ui.sidebarWidth - 96 width: ui.sidebarWidth - 96
}, },
{ {
align: 'right', align: 'right',
@ -241,19 +244,19 @@ pandora.ui.folderList = function(id) {
that = Ox.TableList({ that = Ox.TableList({
columns: columns, columns: columns,
items: items, items: items,
keys: ['query'], keys: ui.section == 'items' ? ['query'] : [],
max: 1, max: 1,
min: 0, min: 0,
pageLength: 1000, pageLength: 1000,
//selected: pandora.getListData().folder == id ? [pandora.user.ui._list] : [], //selected: pandora.getListData().folder == id ? [ui._list] : [],
sort: [{key: 'position', operator: '+'}], sort: [{key: 'position', operator: '+'}],
sortable: id != 'featured' || canEditFeaturedLists, sortable: id != 'featured' || canEditFeatured,
unique: id != 'volumes' ? 'id' : 'name' unique: id != 'volumes' ? 'id' : 'name'
}) })
.css({ .css({
left: 0, left: 0,
top: 0, top: 0,
width: pandora.user.ui.sidebarWidth + 'px' width: ui.sidebarWidth + 'px'
}) })
.bindEvent({ .bindEvent({
add: function(event) { add: function(event) {
@ -284,7 +287,7 @@ pandora.ui.folderList = function(id) {
}); });
}); });
} }
} else if (id == 'favorite' || (id == 'featured' && canEditFeaturedLists)) { } else if (id == 'favorite' || (id == 'featured' && canEditFeatured)) {
// this makes the button trigger a change event, // this makes the button trigger a change event,
// which is already being handled in folders.js // which is already being handled in folders.js
pandora.$ui.manageListsButton[id].options({value: true}); pandora.$ui.manageListsButton[id].options({value: true});
@ -309,7 +312,7 @@ pandora.ui.folderList = function(id) {
} }
} else if (data.key == 'status') { } else if (data.key == 'status') {
var status = that.value(data.id, data.key) == 'private' ? 'public' : 'private'; var status = that.value(data.id, data.key) == 'private' ? 'public' : 'private';
pandora.changeListStatus(data.id, status, function(result) { pandora.changeFolderItemStatus(data.id, status, function(result) {
that.value(result.data.id, 'status', result.data.status); that.value(result.data.id, 'status', result.data.status);
}); });
} else if (data.key == 'path') { } else if (data.key == 'path') {
@ -323,15 +326,15 @@ pandora.ui.folderList = function(id) {
pandora.ui.deleteListDialog(data.ids[0]).open(); pandora.ui.deleteListDialog(data.ids[0]).open();
} else if (id == 'favorite') { } else if (id == 'favorite') {
that.options({selected: []}); that.options({selected: []});
pandora.api.unsubscribeFromList({ pandora.api['unsubscribeFrom' + folderItem]({
id: data.ids[0] id: data.ids[0]
}, function(result) { }, function(result) {
Ox.Request.clearCache(); // fixme: remove Ox.Request.clearCache(); // fixme: remove
that.reloadList(); that.reloadList();
}); });
} else if (id == 'featured' && canEditFeaturedLists) { } else if (id == 'featured' && canEditFeatured) {
that.options({selected: []}); that.options({selected: []});
pandora.api.editList({ pandora.api['edit' + folderItem]({
id: data.ids[0], id: data.ids[0],
status: 'public' status: 'public'
}, function(result) { }, function(result) {
@ -352,7 +355,7 @@ pandora.ui.folderList = function(id) {
}, },
*/ */
init: function(data) { init: function(data) {
pandora.site.sectionFolders[pandora.user.ui.section][i].items = data.items; pandora.site.sectionFolders[ui.section][i].items = data.items;
pandora.$ui.folder[i].$content.css({ pandora.$ui.folder[i].$content.css({
height: data.items * 16 + 'px' height: data.items * 16 + 'px'
}); });
@ -362,7 +365,7 @@ pandora.ui.folderList = function(id) {
pandora.resizeFolders(); pandora.resizeFolders();
}, },
move: function(data) { move: function(data) {
pandora.api.sortLists({ pandora.api['sort' + foldeItem]({
section: id, section: id,
ids: data.ids ids: data.ids
}); });
@ -377,6 +380,7 @@ pandora.ui.folderList = function(id) {
id != id_ && $list.options('selected', []); id != id_ && $list.options('selected', []);
}); });
} }
if (ui.section == 'items') {
pandora.UI.set({ pandora.UI.set({
find: { find: {
conditions: list ? [ conditions: list ? [
@ -385,11 +389,14 @@ pandora.ui.folderList = function(id) {
operator: '&' operator: '&'
} }
}); });
} else {
pandora.UI.set(ui.section.slice(0, -1), list);
}
}, },
submit: function(data) { submit: function(data) {
var data_ = {id: data.id}; var data_ = {id: data.id};
data_[data.key] = data.value; data_[data.key] = data.value;
pandora.api.editList(data_, function(result) { pandora.api['edit' + folderItem](data_, function(result) {
if (result.data.id != data.id) { if (result.data.id != data.id) {
pandora.renameList(data.id, result.data.id, result.data.name, id); pandora.renameList(data.id, result.data.id, result.data.name, id);
pandora.$ui.info.updateListInfo(); pandora.$ui.info.updateListInfo();
@ -397,6 +404,5 @@ pandora.ui.folderList = function(id) {
}); });
} }
}); });
}
return that; return that;
}; };

View file

@ -7,7 +7,9 @@ pandora.ui.folders = function() {
.css({overflowX: 'hidden', overflowY: 'auto'}) .css({overflowX: 'hidden', overflowY: 'auto'})
.bindEvent({ .bindEvent({
resize: pandora.resizeFolders resize: pandora.resizeFolders
}); }),
folderItems = ui.section == 'items' ? 'Lists' : Ox.toTitleCase(ui.section),
folderItem = folderItems.slice(0, -1);
//var $sections = []; //var $sections = [];
pandora.$ui.allItems = pandora.ui.allItems().appendTo(that); pandora.$ui.allItems = pandora.ui.allItems().appendTo(that);
@ -18,15 +20,17 @@ pandora.ui.folders = function() {
pandora.$ui.findListSelect = {}; pandora.$ui.findListSelect = {};
pandora.$ui.findListInput = {}; pandora.$ui.findListInput = {};
pandora.$ui.manageListsButton = {}; pandora.$ui.manageListsButton = {};
if (ui.section == 'items') { pandora.site.sectionFolders[ui.section].forEach(function(folder, i) {
pandora.site.sectionFolders.items.forEach(function(folder, i) {
var extras, $select; var extras, $select;
if (folder.id == 'personal') { if (folder.id == 'personal') {
if (pandora.user.level == 'guest') { if (pandora.user.level == 'guest') {
extras = [ extras = [
infoButton('Personal Lists', 'To create and share your own lists of movies, please sign up or sign in.') infoButton('Personal ' + folderItems, 'To create and share your own ' + (ui.section == 'items'
? 'lists of ' + pandora.site.itemName.plural.toLowerCase()
: ui.section) + ', please sign up or sign in.')
]; ];
} else { } else {
if (ui.section == 'items') {
extras = [ extras = [
pandora.$ui.personalListsMenu = Ox.MenuButton({ pandora.$ui.personalListsMenu = Ox.MenuButton({
items: [ items: [
@ -78,24 +82,55 @@ pandora.ui.folders = function() {
} }
}) })
]; ];
} else {
extras = [
pandora.$ui.personalListsMenu = Ox.MenuButton({
items: [
{ id: 'new' + folderItem.toLowerCase(), title: 'New ' + folderItem },
{},
{ id: 'delete' + folderItem.toLowerCase(), title: 'Delete Selected ' + folderItem + '...', disabled: !ui[ui.section.slice(0,-1)] }
],
title: 'edit',
tooltip: 'Manage Personal ' + folderItems,
type: 'image'
})
.bindEvent({
click: function(data) {
var $list = pandora.$ui.folderList[folder.id];
// fixme: duplicated
if (data.id == 'new' + folderItem.toLowerCase()) {
pandora['add' + folderItem]();
} else if (data.id == 'delete' + folderItem.toLowerCase()) {
pandora.ui.deleteListDialog().open();
}
}
})
.bindEvent('pandora_' + ui.section.slice(0,-1), function(data) {
pandora.$ui.personalListsMenu[
data.value && data.value.length ? 'enableItem' : 'disableItem'
]('delete' + folderItem.toLowerCase());
})
];
}
} }
} else if (folder.id == 'favorite') { } else if (folder.id == 'favorite') {
if (pandora.user.level == 'guest') { if (pandora.user.level == 'guest') {
extras = [infoButton('Favorite Lists', 'To browse and subscribe to shared lists from other users, please sign up or sign in.')]; extras = [infoButton('Favorite ' + folderItems,
'To browse and subscribe to shared ' + folderItems.toLowerCase() + ' from other users, please sign up or sign in.')];
} else { } else {
extras = [pandora.$ui.manageListsButton['favorite'] = Ox.Button({ extras = [pandora.$ui.manageListsButton['favorite'] = Ox.Button({
selectable: true, selectable: true,
style: 'symbol', style: 'symbol',
title: 'Edit', title: 'Edit',
tooltip: 'Manage Favorite Lists', tooltip: 'Manage Favorite ' + folderItems,
type: 'image' type: 'image'
}) })
.bindEvent({ .bindEvent({
change: function(data) { change: function(data) {
var listData; var listData;
Ox.Request.clearCache(); // fixme: remove Ox.Request.clearCache(); // fixme: remove
pandora.site.sectionFolders.items[i].showBrowser = !pandora.site.sectionFolders.items[i].showBrowser; pandora.site.sectionFolders[ui.section][i].showBrowser = !pandora.site.sectionFolders[ui.section][i].showBrowser;
if (pandora.site.sectionFolders.items[i].showBrowser) { if (pandora.site.sectionFolders[ui.section][i].showBrowser) {
pandora.$ui.folderList.favorite.replaceWith( pandora.$ui.folderList.favorite.replaceWith(
pandora.$ui.folderBrowser.favorite = pandora.ui.folderBrowser('favorite') pandora.$ui.folderBrowser.favorite = pandora.ui.folderBrowser('favorite')
); );
@ -107,7 +142,7 @@ pandora.ui.folders = function() {
) { ) {
// the selected list in the favorites browser is not in the favorites folder // the selected list in the favorites browser is not in the favorites folder
pandora.$ui.folderList.favorite.options({selected: []}); pandora.$ui.folderList.favorite.options({selected: []});
if (Ox.getObjectById(pandora.site.sectionFolders.items, 'featured').showBrowser) { if (Ox.getObjectById(pandora.site.sectionFolders[ui.section], 'featured').showBrowser) {
// but in the featured browser // but in the featured browser
pandora.$ui.folderList.featured.options({selected: [listData.id]}); pandora.$ui.folderList.featured.options({selected: [listData.id]});
} else { } else {
@ -127,21 +162,21 @@ pandora.ui.folders = function() {
} }
} else if (folder.id == 'featured') { } else if (folder.id == 'featured') {
if (pandora.user.level != 'admin') { if (pandora.user.level != 'admin') {
extras = [infoButton('Featured Lists', 'Featured lists are selected public lists, picked by the ' + pandora.site.site.name + ' staff.')]; extras = [infoButton('Featured ' + folderItems, 'Featured ' + folderItems.toLowerCase() + ' are selected public ' + folderItems.toLowerCase() + ', picked by the ' + pandora.site.site.name + ' staff.')];
} else { } else {
extras = [pandora.$ui.manageListsButton['featured'] = Ox.Button({ extras = [pandora.$ui.manageListsButton['featured'] = Ox.Button({
selectable: true, selectable: true,
style: 'symbol', style: 'symbol',
title: 'Edit', title: 'Edit',
tooltip: 'Manage Featured Lists', tooltip: 'Manage Featured ' + folderItems,
type: 'image' type: 'image'
}) })
.bindEvent({ .bindEvent({
change: function(data) { change: function(data) {
var listData; var listData;
Ox.Request.clearCache(); // fixme: remove Ox.Request.clearCache(); // fixme: remove
pandora.site.sectionFolders.items[i].showBrowser = !pandora.site.sectionFolders.items[i].showBrowser; pandora.site.sectionFolders[ui.section][i].showBrowser = !pandora.site.sectionFolders[ui.section][i].showBrowser;
if (pandora.site.sectionFolders.items[i].showBrowser) { if (pandora.site.sectionFolders[ui.section][i].showBrowser) {
pandora.$ui.folderList.featured.replaceWith( pandora.$ui.folderList.featured.replaceWith(
pandora.$ui.folderBrowser.featured = pandora.ui.folderBrowser('featured') pandora.$ui.folderBrowser.featured = pandora.ui.folderBrowser('featured')
); );
@ -159,7 +194,7 @@ pandora.ui.folders = function() {
pandora.$ui.folderList.personal.options({selected: [listData.id]}); pandora.$ui.folderList.personal.options({selected: [listData.id]});
} else if ( } else if (
listData.subscribed listData.subscribed
|| Ox.getObjectById(pandora.site.sectionFolders.items, 'favorite').showBrowser || Ox.getObjectById(pandora.site.sectionFolders[ui.section], 'favorite').showBrowser
) { ) {
// but in the favorites folder or browser // but in the favorites folder or browser
pandora.$ui.folderList.favorite.options({selected: [listData.id]}); pandora.$ui.folderList.favorite.options({selected: [listData.id]});
@ -255,7 +290,7 @@ pandora.ui.folders = function() {
}) })
.bindEventOnce({ .bindEventOnce({
init: function(data) { init: function(data) {
if (++counter == 4) { if (++counter == pandora.site.sectionFolders[ui.section].length) {
pandora.$ui.folder.forEach(function($folder) { pandora.$ui.folder.forEach(function($folder) {
that.append($folder); that.append($folder);
}); });
@ -266,7 +301,6 @@ pandora.ui.folders = function() {
}) })
.appendTo(pandora.$ui.folder[i].$content); .appendTo(pandora.$ui.folder[i].$content);
}); });
}
function infoButton(title, text) { function infoButton(title, text) {
return Ox.Button({ return Ox.Button({
style: 'symbol', style: 'symbol',
@ -340,6 +374,13 @@ pandora.ui.folders = function() {
}); });
} }
*/ */
},
pandora_text: function() {
if (!pandora.user.ui.text) {
Ox.forEach(pandora.$ui.folderList, function($list, id) {
$list.options('selected', []);
});
}
} }
}) })
return that; return that;

View file

@ -13,7 +13,10 @@ pandora.ui.listDialog = function(section) {
], listData.type == 'smart' ], listData.type == 'smart'
? [{id: 'query', title: 'Query'}] ? [{id: 'query', title: 'Query'}]
: [] : []
); ),
ui = pandora.user.ui,
folderItems = ui.section == 'items' ? 'Lists' : Ox.toTitleCase(ui.section),
folderItem = folderItems.slice(0, -1);
Ox.getObjectById(tabs, section).selected = true; Ox.getObjectById(tabs, section).selected = true;
pandora.$ui.listDialogTabPanel = Ox.TabPanel({ pandora.$ui.listDialogTabPanel = Ox.TabPanel({
@ -103,7 +106,7 @@ pandora.ui.listDialog = function(section) {
height: 312, height: 312,
// keys: {enter: 'save', escape: 'cancel'}, // keys: {enter: 'save', escape: 'cancel'},
removeOnClose: true, removeOnClose: true,
title: 'List &mdash; ' + Ox.encodeHTMLEntities(listData.name), title: folderItem + ' &mdash; ' + Ox.encodeHTMLEntities(listData.name),
width: width width: width
}); });
@ -117,8 +120,11 @@ pandora.ui.listDialog = function(section) {
}; };
pandora.ui.listGeneralPanel = function(listData) { pandora.ui.listGeneralPanel = function(listData) {
var that = Ox.Element(); var that = Ox.Element(),
pandora.api.findLists({ ui = pandora.user.ui,
folderItems = ui.section == 'items' ? 'Lists' : Ox.toTitleCase(ui.section),
folderItem = folderItems.slice(0, -1);
pandora.api['find' + folderItems]({
query: {conditions: [{key: 'id', value: listData.id, operator: '=='}]}, query: {conditions: [{key: 'id', value: listData.id, operator: '=='}]},
keys: ['description', 'subscribers'] keys: ['description', 'subscribers']
}, function(result) { }, function(result) {
@ -129,7 +135,7 @@ pandora.ui.listGeneralPanel = function(listData) {
tooltip: 'Doubleclick to edit icon' tooltip: 'Doubleclick to edit icon'
}) })
.attr({ .attr({
src: '/list/' + listData.id + '/icon256.jpg?' + Ox.uid() src: '/' + folderItem.toLowerCase() + '/' + listData.id + '/icon256.jpg?' + Ox.uid()
}) })
.css({ .css({
position: 'absolute', position: 'absolute',
@ -157,7 +163,8 @@ pandora.ui.listGeneralPanel = function(listData) {
submit: editName submit: editName
}) })
.appendTo(that), .appendTo(that),
$itemsInput = Ox.Input({ $itemsInput = ui.section == 'items'
? Ox.Input({
disabled: true, disabled: true,
label: 'Items', label: 'Items',
labelWidth: 80, labelWidth: 80,
@ -165,6 +172,21 @@ pandora.ui.listGeneralPanel = function(listData) {
width: 320 width: 320
}) })
.css({position: 'absolute', left: '160px', top: '40px'}) .css({position: 'absolute', left: '160px', top: '40px'})
.appendTo(that)
: Ox.Select({
items: [
{id: 'html', title: 'HMTL'},
{id: 'pdf', title: 'PDF'}
],
label: 'Type',
labelWidth: 80,
value: listData.type,
width: 320
})
.css({position: 'absolute', left: '160px', top: '40px'})
.bindEvent({
change: editType
})
.appendTo(that), .appendTo(that),
$statusSelect = listData.status == 'featured' $statusSelect = listData.status == 'featured'
? Ox.Input({ ? Ox.Input({
@ -216,19 +238,19 @@ pandora.ui.listGeneralPanel = function(listData) {
.appendTo(that); .appendTo(that);
function editDescription(data) { function editDescription(data) {
if (data.value != description) { if (data.value != description) {
pandora.api.editList({ pandora.api['edit' + folderItem]({
id: listData.id, id: listData.id,
description: data.value description: data.value
}, function(result) { }, function(result) {
description = result.data.description; description = result.data.description;
Ox.Request.clearCache('findLists'); Ox.Request.clearCache('find' + folderItems);
pandora.$ui.info.updateListInfo(); pandora.$ui.info.updateListInfo();
}); });
} }
} }
function editName(data) { function editName(data) {
if (data.value != listData.name) { if (data.value != listData.name) {
pandora.api.editList({ pandora.api['edit' + folderItem]({
id: listData.id, id: listData.id,
name: data.value name: data.value
}, function(result) { }, function(result) {
@ -236,10 +258,10 @@ pandora.ui.listGeneralPanel = function(listData) {
pandora.renameList(listData.id, result.data.id, result.data.name); pandora.renameList(listData.id, result.data.id, result.data.name);
listData.id = result.data.id; listData.id = result.data.id;
listData.name = result.data.name; listData.name = result.data.name;
Ox.Request.clearCache('findLists'); Ox.Request.clearCache('find' + folderItems);
pandora.$ui.info.updateListInfo(); pandora.$ui.info.updateListInfo();
pandora.$ui.listDialog.options({ pandora.$ui.listDialog.options({
title: 'List &mdash; ' + Ox.encodeHTMLEntities(listData.name) title: folderItme + ' &mdash; ' + Ox.encodeHTMLEntities(listData.name)
}); });
} }
}); });
@ -248,7 +270,7 @@ pandora.ui.listGeneralPanel = function(listData) {
function editStatus(data) { function editStatus(data) {
var status = data.value; var status = data.value;
$statusSelect.value(status == 'private' ? 'public' : 'private'); $statusSelect.value(status == 'private' ? 'public' : 'private');
pandora.changeListStatus(listData.id, status, function(result) { pandora.changeFolderItemStatus(listData.id, status, function(result) {
listData.status = result.data.status; listData.status = result.data.status;
if (result.data.status == 'private') { if (result.data.status == 'private') {
subscribers = 0; subscribers = 0;
@ -264,6 +286,18 @@ pandora.ui.listGeneralPanel = function(listData) {
); );
}); });
} }
function editType(data) {
var type = data.value;
$itemsInput.value(type == 'html' ? 'html' : 'pdf');
pandora.api.editText({
id: listData.id,
type: type
}, function(result) {
Ox.Request.clearCache('getText');
//fixme: reload text and folder list
$itemsInput.value(result.data.type);
});
}
function getDescriptionHeight() { function getDescriptionHeight() {
return listData.status == 'private' ? 184 : 160; return listData.status == 'private' ? 184 : 160;
} }
@ -282,10 +316,14 @@ pandora.ui.listIconPanel = function(listData) {
var quarter = 0, var quarter = 0,
quarters = ['top-left', 'top-right', 'bottom-left', 'bottom-right'], quarters = ['top-left', 'top-right', 'bottom-left', 'bottom-right'],
ui = pandora.user.ui,
folderItems = ui.section == 'items' ? 'Lists' : Ox.toTitleCase(ui.section),
folderItem = folderItems.slice(0, -1),
$iconPanel = Ox.Element(), $iconPanel = Ox.Element(),
$icon = $('<img>') $icon = $('<img>')
.attr({src: '/list/' + listData.id + '/icon256.jpg?' + Ox.uid()}) .attr({src: '/' + folderItem.toLowerCase() + '/' + listData.id + '/icon256.jpg?' + Ox.uid()})
.css({position: 'absolute', borderRadius: '64px', margin: '16px'}) .css({position: 'absolute', borderRadius: '64px', margin: '16px'})
.appendTo($iconPanel), .appendTo($iconPanel),
@ -295,6 +333,10 @@ pandora.ui.listIconPanel = function(listData) {
$list = Ox.Element(), $list = Ox.Element(),
ui = pandora.user.ui,
folderItems = ui.section == 'items' ? 'Lists' : Ox.toTitleCase(ui.section),
folderItem = folderItems.slice(0, -1),
that = Ox.SplitPanel({ that = Ox.SplitPanel({
elements: [ elements: [
{ {
@ -312,7 +354,7 @@ pandora.ui.listIconPanel = function(listData) {
orientation: 'horizontal' orientation: 'horizontal'
}); });
pandora.api.findLists({ pandora.api['find' + folderItems]({
query: { query: {
conditions: [{key: 'id', value: listData.id, operator: '=='}], conditions: [{key: 'id', value: listData.id, operator: '=='}],
operator: '&' operator: '&'
@ -364,7 +406,7 @@ pandora.ui.listIconPanel = function(listData) {
items: function(data, callback) { items: function(data, callback) {
pandora.api.find(Ox.extend(data, { pandora.api.find(Ox.extend(data, {
query: { query: {
conditions: [{key: 'list', value: listData.id, operator: '=='}], conditions: ui.section == 'items' ? [{key: 'list', value: listData.id, operator: '=='}] : [],
operator: '&' operator: '&'
} }
}), callback); }), callback);
@ -375,7 +417,7 @@ pandora.ui.listIconPanel = function(listData) {
//orientation: 'vertical', //orientation: 'vertical',
selected: posterFrame ? [posterFrame.item] : [], selected: posterFrame ? [posterFrame.item] : [],
size: 128, size: 128,
sort: pandora.user.ui.listSort, sort: ui.section == 'items' ? pandora.user.ui.listSort : pandora.site.user.ui.listSort,
unique: 'id' unique: 'id'
}) })
//.css({width: '144px'}) //.css({width: '144px'})
@ -461,17 +503,17 @@ pandora.ui.listIconPanel = function(listData) {
} else { } else {
posterFrames = Ox.repeat([posterFrame], 4); posterFrames = Ox.repeat([posterFrame], 4);
} }
pandora.api.editList({ pandora.api['edit' + folderItem]({
id: listData.id, id: listData.id,
posterFrames: posterFrames posterFrames: posterFrames
}, function() { }, function() {
$icon.attr({ $icon.attr({
src: '/list/' + listData.id + '/icon256.jpg?' + Ox.uid() src: '/' + folderItem.toLowerCase() + '/' + listData.id + '/icon256.jpg?' + Ox.uid()
}); });
pandora.$ui.folderList[listData.folder].$element pandora.$ui.folderList[listData.folder].$element
.find('img[src*="/' + listData.id + '/"]') .find('img[src*="/' + listData.id + '/"]')
.attr({ .attr({
src: '/list/' + listData.id + '/icon.jpg?' + Ox.uid() src: '/' + folderItem.toLowerCase() + '/' + listData.id + '/icon.jpg?' + Ox.uid()
}); });
pandora.$ui.info.updateListInfo(); pandora.$ui.info.updateListInfo();
pandora.clearListIconCache(listData.id); pandora.clearListIconCache(listData.id);

View file

@ -65,6 +65,12 @@ pandora.ui.mainPanel = function() {
} }
} }
}, },
pandora_section: function(data) {
if (data.value != data.previousValue) {
that.replaceElement(0, pandora.$ui.leftPanel = pandora.ui.leftPanel());
that.replaceElement(1, pandora.$ui.rightPanel = pandora.ui.rightPanel());
}
},
pandora_item: function(data) { pandora_item: function(data) {
if (!data.value || !data.previousValue) { if (!data.value || !data.previousValue) {
that.replaceElement(1, pandora.$ui.rightPanel = pandora.ui.rightPanel()); that.replaceElement(1, pandora.$ui.rightPanel = pandora.ui.rightPanel());

View file

@ -57,6 +57,8 @@ pandora.ui.rightPanel = function() {
} }
} }
}); });
} else if (pandora.user.ui.section == 'texts') {
that = pandora.$ui.text = pandora.ui.text();
} }
return that; return that;
}; };

View file

@ -5,7 +5,7 @@ pandora.ui.sectionButtons = function() {
buttons: [ buttons: [
{id: 'items', title: pandora.site.itemName.plural}, {id: 'items', title: pandora.site.itemName.plural},
{id: 'edits', title: 'Edits', disabled: true}, {id: 'edits', title: 'Edits', disabled: true},
{id: 'texts', title: 'Texts', disabled: true} {id: 'texts', title: 'Texts', disabled: pandora.user.level != 'admin'}
], ],
id: 'sectionButtons', id: 'sectionButtons',
selectable: true, selectable: true,
@ -17,13 +17,7 @@ pandora.ui.sectionButtons = function() {
.bindEvent({ .bindEvent({
change: function(data) { change: function(data) {
var section = data.value; var section = data.value;
if (section == 'items') { pandora.UI.set({section: section});
pandora.URL.set(pandora.Query.toString());
} else if (section == 'clips') {
pandora.URL.set('clips');
} else if (section == 'texts') {
pandora.URL.set('texts');
}
} }
}); });
return that; return that;

58
static/js/pandora/text.js Normal file
View file

@ -0,0 +1,58 @@
'use strict';
pandora.ui.text = function() {
var ui = pandora.user.ui,
canEdit = pandora.site.capabilities.canEditSitePages[pandora.user.level],
that,
text,
$text;
getText(ui.text);
that = Ox.Element()
.bindEvent({
pandora_text: function(data) {
if (ui.text != text) {
text = ui.text;
getText(ui.text);
}
}
});
function getText(id) {
pandora.api.getText({id: id}, function(result) {
if (result.data.type == 'pdf') {
$text && $text.remove();
$text = Ox.Editable({
clickLink: pandora.clickLink,
editable: false,
type: 'textarea',
value: 'REPLACE ME WITH PDF VIEWER'
})
.appendTo(that);
} else {
var text = result.data ? result.data.text : '';
$text && $text.remove();
$text = Ox.Editable({
clickLink: pandora.clickLink,
editable: canEdit,
tooltip: canEdit ? 'Doubleclick to edit' : '',
type: 'textarea',
placeholder: 'No text',
value: text
})
.bindEvent({
submit: function(data) {
Ox.Request.clearCache('getText');
pandora.api.editText({
id: ui.text,
text: data.value
});
}
})
.appendTo(that);
}
});
}
return that;
}

View file

@ -147,10 +147,31 @@ pandora.addList = function() {
}).reloadList(); }).reloadList();
} }
}; };
pandora.addText = function() {
var $folderList = pandora.$ui.folderList.personal;
pandora.api.addText({name: 'Untitled'}, function(result) {
reloadFolder(result.data.id);
});
function reloadFolder(newId) {
pandora.$ui.folder[0].options({collapsed: false});
Ox.Request.clearCache('findTexts');
$folderList.bindEventOnce({
load: function(data) {
$folderList.gainFocus()
.options({selected: [newId]})
.editCell(newId, 'name', true);
pandora.UI.set(pandora.user.ui.section.slice(0, -1), newId);
}
}).reloadList();
}
}
pandora.changeListStatus = function(id, status, callback) { pandora.changeFolderItemStatus = function(id, status, callback) {
var ui = pandora.user.ui,
folderItems = ui.section == 'items' ? 'Lists' : Ox.toTitleCase(ui.section),
folderItem = folderItems.slice(0, -1);
if (status == 'private') { if (status == 'private') {
pandora.api.findLists({ pandora.api['find' + folderItems]({
query: {conditions: [{key: 'id', value: id, operator: '=='}]}, query: {conditions: [{key: 'id', value: id, operator: '=='}]},
keys: ['name', 'subscribers'] keys: ['name', 'subscribers']
}, function(result) { }, function(result) {
@ -168,14 +189,14 @@ pandora.changeListStatus = function(id, status, callback) {
} }
}).open(); }).open();
} else { } else {
changeListStatus(); changeFolderItemStatus();
} }
}); });
} else { } else {
changeListStatus(); changeFolderItemStatus();
} }
function changeListStatus() { function changeFolderItemStatus() {
pandora.api.editList({ pandora.api['edit' + folderItem]({
id: id, id: id,
status: status status: status
}, callback); }, callback);
@ -606,7 +627,8 @@ pandora.getInfoHeight = function(includeHidden) {
return height; return height;
} }
pandora.getItemByIdOrTitle = function(str, callback) { pandora.getItemByIdOrTitle = function(type, str, callback) {
if (type == pandora.site.itemName.plural.toLowerCase()) {
var sortKey = Ox.getObjectById(pandora.site.itemKeys, 'votes') var sortKey = Ox.getObjectById(pandora.site.itemKeys, 'votes')
? 'votes' ? 'votes'
: 'timesaccessed'; : 'timesaccessed';
@ -642,6 +664,9 @@ pandora.getItemByIdOrTitle = function(str, callback) {
}); });
} }
}); });
} else {
callback(str);
}
} }
pandora.getItemFind = function(find) { pandora.getItemFind = function(find) {
@ -706,7 +731,11 @@ pandora.getItemIdAndPosition = function() {
pandora.getListData = function(list) { pandora.getListData = function(list) {
var data = {}, folder; var data = {}, folder;
if (pandora.user.ui.section == 'items') {
list = Ox.isUndefined(list) ? pandora.user.ui._list : list; list = Ox.isUndefined(list) ? pandora.user.ui._list : list;
} else {
list = Ox.isUndefined(list) ? pandora.user.ui[pandora.user.ui.section.slice(0, -1)] : list;
}
if (list) { if (list) {
Ox.forEach(pandora.$ui.folderList, function($list, id) { Ox.forEach(pandora.$ui.folderList, function($list, id) {
var ret = true; var ret = true;
@ -726,8 +755,12 @@ pandora.getListData = function(list) {
// FIXME: Is there a `return ret` statement missing here? // FIXME: Is there a `return ret` statement missing here?
}); });
if (folder) { if (folder) {
data = pandora.$ui.folderList[folder].value(pandora.user.ui._list); data = pandora.$ui.folderList[folder].value(list);
if (pandora.user.ui.section == 'item') {
data.editable = data.user == pandora.user.username && data.type == 'static'; data.editable = data.user == pandora.user.username && data.type == 'static';
} else {
data.editable = data.user == pandora.user.username;
}
data.folder = folder; data.folder = folder;
} }
} }
@ -1076,6 +1109,7 @@ pandora.renameList = function(oldId, newId, newName, folder) {
folder = folder || pandora.getListData(oldId).folder; folder = folder || pandora.getListData(oldId).folder;
pandora.$ui.folderList[folder].value(oldId, 'name', newName); pandora.$ui.folderList[folder].value(oldId, 'name', newName);
pandora.$ui.folderList[folder].value(oldId, 'id', newId); pandora.$ui.folderList[folder].value(oldId, 'id', newId);
if (pandora.user.ui.section == 'items') {
pandora.$ui.toolbar.updateListName(newId); pandora.$ui.toolbar.updateListName(newId);
pandora.UI.set({ pandora.UI.set({
find: { find: {
@ -1083,17 +1117,20 @@ pandora.renameList = function(oldId, newId, newName, folder) {
operator: '&' operator: '&'
} }
}, false); }, false);
} else {
pandora.UI.set(pandora.user.ui.section.slice(0, -1), newId);
}
}; };
pandora.resizeFilters = function(width) { pandora.resizeFilters = function(width) {
pandora.user.ui.filterSizes = pandora.getFilterSizes(); pandora.user.ui.filterSizes = pandora.getFilterSizes();
pandora.$ui.browser pandora.$ui.browser && pandora.$ui.browser
.size(0, pandora.user.ui.filterSizes[0]) .size(0, pandora.user.ui.filterSizes[0])
.size(2, pandora.user.ui.filterSizes[4]); .size(2, pandora.user.ui.filterSizes[4]);
pandora.$ui.filtersInnerPanel pandora.$ui.filtersInnerPanel && pandora.$ui.filtersInnerPanel
.size(0, pandora.user.ui.filterSizes[1]) .size(0, pandora.user.ui.filterSizes[1])
.size(2, pandora.user.ui.filterSizes[3]); .size(2, pandora.user.ui.filterSizes[3]);
pandora.$ui.filters.forEach(function($list, i) { pandora.$ui.filters && pandora.$ui.filters.forEach(function($list, i) {
$list.resizeColumn('name', pandora.user.ui.filterSizes[i] - 44 - Ox.UI.SCROLLBAR_SIZE); $list.resizeColumn('name', pandora.user.ui.filterSizes[i] - 44 - Ox.UI.SCROLLBAR_SIZE);
if (pandora.user.ui.showFlags) { if (pandora.user.ui.showFlags) {
$list.find('.flagname').css({width: pandora.user.ui.filterSizes[i] - 68 - Ox.UI.SCROLLBAR_SIZE}) $list.find('.flagname').css({width: pandora.user.ui.filterSizes[i] - 68 - Ox.UI.SCROLLBAR_SIZE})
@ -1103,18 +1140,16 @@ pandora.resizeFilters = function(width) {
pandora.resizeFolders = function() { pandora.resizeFolders = function() {
var width = pandora.getFoldersWidth(), var width = pandora.getFoldersWidth(),
columnWidth = {}; columnWidth = {},
if (pandora.user.ui.section == 'items') { sectionWidth = pandora.user.ui.section == 'items'? 96 : 32;
columnWidth = {user: parseInt((width - 96) * 0.4)}; columnWidth = {user: parseInt((width - (sectionWidth)) * 0.4)};
columnWidth.name = (width - 96) - columnWidth.user; columnWidth.name = (width - sectionWidth) - columnWidth.user;
}
Ox.Log('', 'RESIZE FOLDERS', width); Ox.Log('', 'RESIZE FOLDERS', width);
pandora.$ui.allItems.resizeElement(width - 104); pandora.$ui.allItems.resizeElement(width - 104);
Ox.forEach(pandora.$ui.folderList, function($list, id) { Ox.forEach(pandora.$ui.folderList, function($list, id) {
var pos = Ox.getIndexById(pandora.site.sectionFolders[pandora.user.ui.section], id); var pos = Ox.getIndexById(pandora.site.sectionFolders[pandora.user.ui.section], id);
pandora.$ui.folder[pos].css({width: width + 'px'}); pandora.$ui.folder[pos].css({width: width + 'px'});
$list.css({width: width + 'px'}); $list.css({width: width + 'px'});
if (pandora.user.ui.section == 'items') {
if (pandora.site.sectionFolders[pandora.user.ui.section][pos].showBrowser) { if (pandora.site.sectionFolders[pandora.user.ui.section][pos].showBrowser) {
pandora.$ui.findListInput[id].options({ pandora.$ui.findListInput[id].options({
width: width - 24 width: width - 24
@ -1124,7 +1159,6 @@ pandora.resizeFolders = function() {
} else { } else {
$list.resizeColumn(id == 'favorite' ? 'id' : 'name', width - 96); $list.resizeColumn(id == 'favorite' ? 'id' : 'name', width - 96);
} }
}
if (!pandora.user.ui.showFolder[pandora.user.ui.section][id]) { if (!pandora.user.ui.showFolder[pandora.user.ui.section][id]) {
pandora.$ui.folder[pos].updatePanel(); pandora.$ui.folder[pos].updatePanel();
} }
@ -1135,6 +1169,7 @@ pandora.resizeWindow = function() {
// FIXME: a lot of this throws errors on load // FIXME: a lot of this throws errors on load
pandora.$ui.leftPanel && pandora.$ui.leftPanel.size(2, pandora.getInfoHeight(true)); pandora.$ui.leftPanel && pandora.$ui.leftPanel.size(2, pandora.getInfoHeight(true));
pandora.resizeFolders(); pandora.resizeFolders();
if (pandora.user.ui.section == 'item') {
if (!pandora.user.ui.item) { if (!pandora.user.ui.item) {
pandora.resizeFilters(pandora.$ui.rightPanel.width()); pandora.resizeFilters(pandora.$ui.rightPanel.width());
if (pandora.user.ui.listView == 'clips') { if (pandora.user.ui.listView == 'clips') {
@ -1192,9 +1227,11 @@ pandora.resizeWindow = function() {
pandora.$ui.calendar.resizeCalendar(); pandora.$ui.calendar.resizeCalendar();
} }
} }
}
}; };
pandora.selectList = function() { pandora.selectList = function() {
if (pandora.user.ui.section == 'items') {
if (pandora.user.ui._list) { if (pandora.user.ui._list) {
pandora.api.findLists({ pandora.api.findLists({
keys: ['status', 'user'], keys: ['status', 'user'],
@ -1218,6 +1255,20 @@ pandora.selectList = function() {
} }
}); });
} }
} else {
var id = pandora.user.ui[pandora.user.ui.section.slice(0,-1)];
if (id) {
pandora.api.getText({id: id}, function(result) {
var folder;
if (result.data.id) {
folder = result.data.status == 'featured' ? 'featured' : (
result.data.user == pandora.user.username ? 'personal' : 'favorite'
);
pandora.$ui.folderList[folder].options({selected: [id]});
}
});
}
}
}; };
pandora.beforeunloadWindow = function() { pandora.beforeunloadWindow = function() {