From 8f5446e46bd97f3ec38735883d72ff595823b466 Mon Sep 17 00:00:00 2001 From: rolux Date: Fri, 5 Aug 2011 18:26:27 +0000 Subject: [PATCH] updating info view --- pandora/item/models.py | 2 + static/js/pandora.js | 5 +- static/js/pandora/ui/infoView.js | 429 +++++++++++++++++++++++++++++++ static/js/pandora/ui/item.js | 12 +- static/json/pandora.json | 1 + 5 files changed, 446 insertions(+), 3 deletions(-) create mode 100644 static/js/pandora/ui/infoView.js diff --git a/pandora/item/models.py b/pandora/item/models.py index f8e41cbe0..9ca5b817c 100644 --- a/pandora/item/models.py +++ b/pandora/item/models.py @@ -439,6 +439,8 @@ class Item(models.Model): if 'reviews' in i: i['reviews'] = self.reviews() + if 'cast' in i and isinstance(i['cast'][0], list): + i['cast'] = map(lambda x: {'actor': x[0], 'character': x[1]}, i['cast']) if not keys or 'poster' in keys: i['poster'] = self.get_poster() diff --git a/static/js/pandora.js b/static/js/pandora.js index 04b398d31..0b14c6c1f 100644 --- a/static/js/pandora.js +++ b/static/js/pandora.js @@ -153,6 +153,7 @@ Ox.load('Geo', function() { } else { //Ox.print('pandora.$ui.window.resize'); pandora.$ui.browser.scrollToSelection(); + pandora.user.ui.itemView == 'info' && pandora.$ui.item.resize(); pandora.user.ui.itemView == 'player' && pandora.$ui.player.options({ // fixme: duplicated height: pandora.$ui.contentPanel.size(1), @@ -163,8 +164,8 @@ Ox.load('Geo', function() { height: pandora.$ui.contentPanel.size(1), width: pandora.$ui.document.width() - pandora.$ui.mainPanel.size(0) - 1 }); - pandora.user.ui.itemView == 'frames' && pandora.$ui.item.resize(); - pandora.user.ui.itemView == 'posters' && pandora.$ui.item.resize(); + //pandora.user.ui.itemView == 'frames' && pandora.$ui.item.resize(); + //pandora.user.ui.itemView == 'posters' && pandora.$ui.item.resize(); } } diff --git a/static/js/pandora/ui/infoView.js b/static/js/pandora/ui/infoView.js new file mode 100644 index 000000000..bc40cf43b --- /dev/null +++ b/static/js/pandora/ui/infoView.js @@ -0,0 +1,429 @@ +pandora.ui.infoView = function(data) { + + var listWidth = 144 + Ox.UI.SCROLLBAR_SIZE, + margin = 8, + posterRatio = data.poster.width / data.poster.height, + posterWidth = posterRatio > 1 ? 256 : Math.round(256 * posterRatio), + posterHeight = posterRatio < 1 ? 256 : Math.round(256 / posterRatio), + posterLeft = Math.floor((256 - posterWidth) / 2), + editPoster = false, + that = Ox.Element(), + $list, + $info = $('
') + .css({ + position: 'absolute', + left: pandora.user.level == 'admin' ? -listWidth + 'px' : 0, + top: 0, + right: 0, + }) + .appendTo(that.$element), + $data = Ox.Container() + .css({ + position: 'absolute', + left: (pandora.user.level == 'admin' ? listWidth : 0) + 'px', + top: 0, + right: 0, + height: pandora.$ui.contentPanel.size(1) + 'px' + }) + .appendTo($info), + $poster = $('') + .attr({ + src: '/' + data.id + '/poster.jpg' + }) + .css({ + position: 'absolute', + left: margin + posterLeft + 'px', + top: margin + 'px', + width: posterWidth + 'px', + height: posterHeight + 'px', + cursor: pandora.user.level == 'admin' ? 'pointer' : 'default' + }) + .appendTo($data.$element), + $reflection = $('
') + .css({ + display: 'block', + position: 'absolute', + left: margin + 'px', + top: margin + posterHeight + 'px', + width: '256px', + height: '128px', + overflow: 'hidden' + }) + .appendTo($data.$element), + $reflectionPoster = $('') + .attr({ + src: '/' + data.id + '/poster.jpg' + }) + .css({ + position: 'absolute', + left: posterLeft + 'px', + width: posterWidth + 'px', + height: posterHeight + 'px', + MozTransform: 'scaleY(-1)', + WebkitTransform: 'scaleY(-1)' + }) + .appendTo($reflection), + $reflectionGradient = $('
') + .css({ + display: 'block', + position: 'absolute', + left: margin + 'px', + width: '256px', + height: '128px' + }) + .css('background', '-moz-linear-gradient(top, rgba(16, 16, 16, 0.75), rgba(16, 16, 16, 1))') + .css('background', '-webkit-linear-gradient(top, rgba(16, 16, 16, 0.75), rgba(16, 16, 16, 1))') + .appendTo($reflection), + $text = $('
') + .css({ + position: 'absolute', + left: margin + 256 + margin + 'px', + top: margin + 'px', + right: margin + 'px' + }) + .appendTo($data.$element); + Ox.print('DATA', data); + ['title', 'director'].forEach(function(key) { + $('
') + .css({ + marginTop: key == 'title' ? '-2px' : '2px', + fontWeight: 'bold', + fontSize: '13px', + MozUserSelect: 'text', + WebkitUserSelect: 'text' + }) + .html(formatValue(data[key], key == 'director' ? 'director' : null)) + .appendTo($text); + }); + var $div = $('
') + .css({ + marginTop: '4px', + textAlign: 'justify' + }) + .appendTo($text); + ['country', 'year', 'language', 'runtime'].forEach(function(key) { + data[key] && $('') + .html( + formatKey(key) + + (key == 'runtime' ? Math.round(data[key] / 60) + ' min' : formatValue(data[key], key == 'runtime' ? null : key)) + + '  ' + ) + .appendTo($div); + }); + // fixme: should be camelCase! + data.alternative_titles && $('
') + .css({ + marginTop: '4px', + textAlign: 'justify', + MozUserSelect: 'text', + WebkitUserSelect: 'text' + }) + .html( + formatKey('Alternative Titles') + data.alternative_titles.map(function(value) { + return value[0] + ( + value[1] + ? ' (' + value[1] + ')' + : '' + ); + }).join(', ') + ) + .appendTo($text); + $div = $('
') + .css({ + marginTop: '4px', + textAlign: 'justify', + MozUserSelect: 'text', + WebkitUserSelect: 'text' + }) + .appendTo($text); + + ['writer', 'producer', 'cinematographer', 'editor'].forEach(function(key) { + data[key] && $('') + .html( + formatKey(key) + formatValue(data[key], 'name') + '  ' + ) + .appendTo($div); + }); + + ['cast', 'genre', 'keyword'].forEach(function(key) { + data[key] && $('
') + .css({ + marginTop: '4px', + textAlign: 'justify' + }) + .html( + formatKey(key == 'keyword' ? 'keywords' : key) + + (key == 'cast' ? data[key].map(function(value) { + value.character = value.character.replace('(uncredited)', '').trim(); + return formatValue(value.actor, 'name') + ( + value.character + ? ' (' + formatValue(value.character, 'name') + ')' + : '' + ); + }).join(', ') : formatValue(data[key], key == 'cast' ? 'name' : key)) + ) + .appendTo($text); + }); + + data.summary && $('
') + .css({ + marginTop: '4px', + textAlign: 'justify', + MozUserSelect: 'text', + WebkitUserSelect: 'text' + }) + .html( + formatKey('summary') + data.summary + ) + .appendTo($text); + + data.trivia && data.trivia.forEach(function(value) { + $('
') + .css({ + display: 'table-row' + }) + .append( + $('
') + .css({ + //display: 'inline', + display: 'table-cell', + //float: 'left', + width: '12px', + marginTop: '4px', + paddingBottom: '4px' + }) + .html('') + ) + .append( + $('
') + .css({ + //clear: 'both', + display: 'table-cell', + //float: 'left', + //width: '100px', + paddingTop: '4px', + textAlign: 'justify', + MozUserSelect: 'text', + WebkitUserSelect: 'text' + }) + .html(value) + ) + .append( + $('
').css({clear: 'both'}) + ) + .appendTo($text); + }); + + data.filming_locations && $('
') + .css({ + marginTop: '4px', + textAlign: 'justify', + MozUserSelect: 'text', + WebkitUserSelect: 'text' + }) + .html( + formatKey('Filming Locations') + data.filming_locations.join('; ') + ) + .appendTo($text); + + data.releasedate && $('
') + .css({ + marginTop: '4px', + textAlign: 'justify', + MozUserSelect: 'text', + WebkitUserSelect: 'text' + }) + .html( + formatKey('Release Date') + Ox.formatDate(data.releasedate, '%A, %B %e, %Y') + ) + .appendTo($text); + + if (data.budget || data.gross || data.profit) { + $div = $('
') + .css({ + marginTop: '4px', + textAlign: 'justify', + MozUserSelect: 'text', + WebkitUserSelect: 'text' + }) + .appendTo($text); + ['budget', 'gross', 'profit'].forEach(function(key) { + data[key] && $('') + .html( + formatKey(key) + data[key] + '  ' + ) + .appendTo($div); + }); + } + + if (data.rating || data.votes) { + $div = $('
') + .css({ + marginTop: '4px', + textAlign: 'justify', + MozUserSelect: 'text', + WebkitUserSelect: 'text' + }) + .appendTo($text); + ['rating', 'votes'].forEach(function(key) { + data[key] && $('') + .html( + formatKey(key) + Ox.formatNumber(data[key]) + '  ' + ) + .appendTo($div); + }); + } + + if (data.connections) { + $div = $('
') + .css({ + marginTop: '4px', + textAlign: 'justify', + MozUserSelect: 'text', + WebkitUserSelect: 'text' + }) + .appendTo($text); + Ox.forEach(data.connections, function(movies, key) { + $('') + .html( + formatKey(key) + formatValue(movies) + '  ' + ) + .appendTo($div); + }); + } + + data.reviews && $('
') + .css({ + marginTop: '4px', + textAlign: 'justify', + MozUserSelect: 'text', + WebkitUserSelect: 'text' + }) + .html( + formatKey('reviews') + data.reviews.map(function(review) { + return '' + review.source + '' + }).join(', ') + ) + .appendTo($text); + + $('
').css({height: '8px'}).appendTo($text); + + if (pandora.user.level == 'admin') { + var icon = 'posters', + selectedImage = {}; + $poster.bind({ + click: function() { + if (!editPoster) { + $info.animate({ + left: 0 + }, 250); + editPoster = true; + } else { + $info.animate({ + left: -listWidth + 'px' + }, 250); + editPoster = false; + } + } + }); + + pandora.api.get({ + id: data.id, + keys: [icon] + }, function(result) { + Ox.print('RESULT', result.data) + var images = result.data[icon]; + selectedImage = images.filter(function(image) { + return image.selected; + })[0]; + $list = Ox.IconList({ + item: function(data, sort, size) { + var ratio = data.width / data.height; + size = size || 128; + return { + height: ratio <= 1 ? size : size / ratio, + id: data['id'], + info: data.width + ' x ' + data.height + ' px', + title: icon == 'posters' ? data.source : Ox.formatDuration(data.position), + url: data.url, + width: ratio >= 1 ? size : size * ratio + } + }, + items: images, + keys: icon == 'posters' + ? ['index', 'source', 'width', 'height', 'url'] + : ['index', 'position', 'width', 'height', 'url'], + max: 1, + min: 1, + orientation: 'vertical', + selected: [selectedImage['index']], + size: 128, + sort: [{key: 'index', operator: '+'}], + unique: 'index' + }) + .css({ + display: 'block', + position: 'absolute', + left: 0, + top: 0, + width: listWidth + 'px', + height: pandora.$ui.contentPanel.size(1) + 'px' + }) + .bindEvent({ + select: function(event) { + var index = event.ids[0]; + selectedImage = images.filter(function(image) { + return image.index == index; + })[0]; + //renderPreview(selectedImage); + pandora.api[icon == 'posters' ? 'setPoster' : 'setPosterFrame'](Ox.extend({ + id: data.id + }, icon == 'posters' ? { + source: selectedImage.source + } : { + position: selectedImage.index // fixme: api slightly inconsistent + }), function(result) { + var imageRatio = selectedImage.width / selectedImage.height; + $('img[src*="/' + item + '/poster"]').each(function() { + var $this = $(this), + size = Math.max($this.width(), $this.height()), + src = $this.attr('src').split('?')[0] + '?' + Ox.uid(); + $('') + .attr({src: src}) + .load(function() { + $this.attr({src: src}); + icon == 'posters' && $this.css(imageRatio < 1 ? { + width: Math.round(size * imageRatio) + 'px', + height: size + 'px' + } : { + width: size + 'px', + height: Math.round(size / imageRatio) + 'px' + }); + }); + }); + }); + } + }) + .appendTo($info); + }); + } + + function formatKey(key) { + return '' + Ox.toTitleCase(key) + ': '; + } + + function formatValue(value, key) { + return (Ox.isArray(value) ? value : [value]).map(function(value) { + return key ? '' + value + '' : value; + }).join(', '); + } + + that.resize = function() { + var height = pandora.$ui.contentPanel.size(1); + $list && $list.css({height: height + 'px'}); + $data.css({height: height + 'px'}); + }; + + return that; + +} \ No newline at end of file diff --git a/static/js/pandora/ui/item.js b/static/js/pandora/ui/item.js index 24cf831a6..d9f5d9ccf 100644 --- a/static/js/pandora/ui/item.js +++ b/static/js/pandora/ui/item.js @@ -59,7 +59,7 @@ pandora.ui.item = function() { })); } else if (pandora.user.ui.itemView == 'info') { //Ox.print('result.data', result.data) - if (pandora.user.level == 'admin') { + if (pandora.user.level == 'admin' && false) { var $form, $edit = Ox.Element() .append($form = Ox.FormElementGroup({ @@ -103,6 +103,15 @@ pandora.ui.item = function() { })); pandora.$ui.contentPanel.replaceElement(1, pandora.$ui.item = $edit); } else { + pandora.$ui.contentPanel.replaceElement(1, + pandora.$ui.item = pandora.ui.infoView(result.data) + .bindEvent({ + resize: function() { + pandora.$ui.item.resize(); + } + }) + ); + /* $.get('/static/html/itemInfo.html', {}, function(template) { //Ox.print(template); var posterRatio = result.data.poster.width / result.data.poster.height; @@ -113,6 +122,7 @@ pandora.ui.item = function() { pandora.$ui.item = Ox.Element().append($.tmpl(template, result.data)) ); }); + */ } } else if (pandora.user.ui.itemView == 'map') { diff --git a/static/json/pandora.json b/static/json/pandora.json index b2bb587a1..b9b9b3058 100644 --- a/static/json/pandora.json +++ b/static/json/pandora.json @@ -40,5 +40,6 @@ "js/pandora/ui/appPanel.js", "js/pandora/ui/flipbook.js", "js/pandora/ui/editor.js", + "js/pandora/ui/infoView.js", "js/pandora/ui/mediaView.js" ]