Bug 622610 - Screenshot ordering

This commit is contained in:
Gregory Koberger 2011-01-11 11:53:03 -08:00
Родитель ff9e3d7aa2
Коммит db15fa630f
11 изменённых файлов: 108 добавлений и 16 удалений

Просмотреть файл

@ -1164,11 +1164,12 @@ class Preview(amo.models.ModelBase):
filetype = models.CharField(max_length=25)
thumbtype = models.CharField(max_length=25)
caption = TranslatedField()
highlight = models.BooleanField(default=False)
position = models.IntegerField(default=0)
class Meta:
db_table = 'previews'
ordering = ('-highlight', 'created')
ordering = ('position', 'created')
def flush_urls(self):
urls = ['*/addon/%d/' % self.addon_id,

Просмотреть файл

@ -337,7 +337,6 @@
"created": "2008-05-03 10:03:27",
"modified": "2008-05-03 10:03:28",
"thumbtype": "image/png",
"highlight": 1,
"addon": 4664
},
"model": "addons.preview",

Просмотреть файл

@ -171,7 +171,6 @@
"created": "2007-03-05 09:54:15",
"modified": null,
"thumbtype": "image/png",
"highlight": 0,
"addon": 159
}
}

Просмотреть файл

@ -51,7 +51,7 @@
{%- if new_api -%}
<previews>
{%- for preview in addon.previews.all() -%}
<preview primary="{{ preview.highlight|int }}">
<preview position="{{ preview.position|int }}">
<full type="{{ preview.filetype }}">
{{ preview.image_url|urlparams(src='api') }}
</full>

Просмотреть файл

@ -270,7 +270,7 @@ class APITest(TestCase):
"%s/en-US/firefox/user/2519/?src=api</link>"
% settings.SITE_URL,
"<previews>",
"""<preview primary="1">""",
"""<preview position="0">""",
"<caption>"
"TwitterBar places an icon in the address bar.</caption>",
"""<full type="image/png">""",

Просмотреть файл

@ -505,7 +505,7 @@ class PreviewForm(happyforms.ModelForm):
class Meta:
model = Preview
fields = ('caption', 'file_upload', 'upload_hash', 'id')
fields = ('caption', 'file_upload', 'upload_hash', 'id', 'position')
class BasePreviewFormSet(BaseModelFormSet):

Просмотреть файл

@ -85,6 +85,7 @@
<div id="file-list">
{% for form in preview_form.forms %}
<div class="preview">
<span class="handle">&nbsp;</span>
<div class="preview-thumb">
{% if form.instance.id %}
<img src="{{ form.instance.thumbnail_url }}">
@ -99,6 +100,9 @@
{{ form.caption|safe }}
<a href="#" class="remove">x</a>
</div>
<div class="js-hidden position">
{{ form.position|safe }}
</div>
<div class="preview_extra">
{{ form.upload_hash|safe }}
</div>

Просмотреть файл

@ -1651,7 +1651,8 @@ class TestEdit(test_utils.TestCase):
fields = []
for i in range(amount):
fields.append(self.formset_new_form(caption='hi',
upload_hash=upload_hash))
upload_hash=upload_hash,
position=i))
data_formset = self.formset_media(*fields)
self.get_url('media', True)
@ -1669,6 +1670,7 @@ class TestEdit(test_utils.TestCase):
edited = {'caption': 'bye',
'upload_hash': '',
'id': preview.id,
'position': preview.position,
'file_upload': None}
data_formset = self.formset_media(edited, initial_count=1)
@ -1678,12 +1680,41 @@ class TestEdit(test_utils.TestCase):
eq_(str(self.get_addon().previews.all()[0].caption), 'bye')
eq_(len(self.get_addon().previews.all()), 1)
def test_edit_media_preview_reorder(self):
self.preview_add(3)
previews = self.get_addon().previews.all()
base = dict(upload_hash='', file_upload=None)
# Three preview forms were generated; mix them up here.
a = dict(caption="first", position=1, id=previews[2].id)
b = dict(caption="second", position=2, id=previews[0].id)
c = dict(caption="third", position=3, id=previews[1].id)
a.update(base)
b.update(base)
c.update(base)
# Add them in backwards ("third", "second", "first")
data_formset = self.formset_media(c, b, a, initial_count=3)
eq_(data_formset['files-0-caption'], 'third')
eq_(data_formset['files-1-caption'], 'second')
eq_(data_formset['files-2-caption'], 'first')
self.client.post(self.get_url('media', True), data_formset)
# They should come out "first", "second", "third"
eq_(self.get_addon().previews.all()[0].caption, 'first')
eq_(self.get_addon().previews.all()[1].caption, 'second')
eq_(self.get_addon().previews.all()[2].caption, 'third')
def test_edit_media_preview_delete(self):
self.preview_add()
preview = self.get_addon().previews.get()
edited = {'DELETE': 'checked',
'upload_hash': '',
'id': preview.id,
'position': 0,
'file_upload': None}
data_formset = self.formset_media(edited, initial_count=1)

Просмотреть файл

@ -349,6 +349,7 @@ form .char-count b {
margin-bottom: 15px;
padding-bottom: 15px;
border-bottom: 1px dotted #ADD0DC;
background-color: #fff;
}
#file-list > div:last-child {
@ -388,7 +389,11 @@ form .char-count b {
}
.preview-thumb {
text-align: center;
-moz-background-size: contain;
-webkit-background-size: contain;
background-size: contain;
background-position: center center;
background-repeat: no-repeat;
border: 3px solid #D2EDF5;
float: left;
height: 94px;
@ -396,9 +401,9 @@ form .char-count b {
width: 125px;
}
.preview-thumb img {
max-width: 125px;
max-height: 94px;
.preview-thumb.error-loading {
border-color: #C63717;
opacity: 0.5;
}
.edit-previews-readonly .preview-thumb {
@ -863,13 +868,18 @@ h3 a.subscribe-feed:hover {
#author_list li > select {
margin-right: .5em;
}
#author_list .handle {
#author_list .handle,
#file-list .handle {
width: 20px;
height: 16px;
display: inline-block;
cursor: move;
background: url(../../img/zamboni/icons/icon-draggable.png) no-repeat 0 center;
}
#file-list .handle {
display: block;
float: left;
}
#author_list .blank * {
display: none;
}

Просмотреть файл

@ -254,6 +254,7 @@ function addonFormSubmit() {
}
});
});
reorderPreviews();
z.refreshL10n();
})(parent_div);
}
@ -316,6 +317,31 @@ function create_new_preview_field() {
return last;
}
function renumberPreviews() {
previews = $("#file-list").children(".preview:visible");
previews.each(function(i, el) {
$(this).find(".position input").val(i);
});
$(previews).find(".handle").toggle(previews.length > 1);
}
function reorderPreviews() {
var preview_list = $("#file-list");
if (preview_list.length) {
preview_list.sortable({
items: ".preview:visible",
handle: ".handle",
containment: preview_list,
tolerance: "pointer",
update: renumberPreviews
});
renumberPreviews();
}
}
function imageUploadFile(f, url, parent_form, callbacks) {
var data = f.getAsBinary(),
file = {},
@ -338,6 +364,7 @@ function imageUploadFile(f, url, parent_form, callbacks) {
if(file.type != 'image/jpeg' && file.type != 'image/png') {
callbacks.upload_errors([gettext("Icons must be either PNG or JPG.")]);
callbacks.upload_finished();
return;
}
@ -413,6 +440,7 @@ var initUploadPreview = (function(){
$('#edit-addon-media .listing-footer button').attr('disabled', false);
}
$(form).find('.preview-thumb').removeClass('loading');
renumberPreviews();
};
callbacks.upload_success = function(upload_hash){
@ -421,9 +449,11 @@ var initUploadPreview = (function(){
callbacks.upload_start = function(){
$(form).find('.preview-thumb').addClass('loading');
$('<img>').appendTo($('.preview-thumb', form)).attr('src', f.getAsDataURL());
$('.preview-thumb', form).css('background-image', 'url('
+ f.getAsDataURL() + ')');
$('#edit-addon-media .listing-footer button').attr('disabled', true);
outstanding_uploads++;
renumberPreviews();
};
callbacks.upload_errors = function(errors){
@ -435,7 +465,11 @@ var initUploadPreview = (function(){
$(error_list).append('<li>' + v + '</li>');
});
$el.find('.edit-previews-text').addClass('error').html(error).append(error_list);
$el.find('.preview-thumb').addClass('error-loading');
$el.find('.edit-previews-text').addClass('error')
.html(error)
.append(error_list);
$el.find('[name^=files-]').remove();
};
@ -450,7 +484,7 @@ var initUploadPreview = (function(){
e.preventDefault();
var row = $(this).closest(".preview");
row.find(".delete input").attr("checked", "checked");
row.hide();
row.slideUp(500, renumberPreviews);
});
}
})();
@ -1614,3 +1648,4 @@ $(document).ready(function() {
$('#addon-validator-suite').trigger('validate');
});

Просмотреть файл

@ -0,0 +1,13 @@
ALTER TABLE previews
ADD COLUMN position TINYINT(11) unsigned DEFAULT 0 AFTER highlight;
CREATE INDEX addon_position_created_idx
ON previews (`addon_id`, `position`, `created`);
UPDATE previews
SET position=1 WHERE highlight=0;
ALTER TABLE previews
DROP COLUMN highlight;