From 6e0790c35420df4a7ac0a0a11da1b523eabe61b9 Mon Sep 17 00:00:00 2001 From: Giorgos Logiotatidis Date: Mon, 12 Jun 2017 10:38:21 +0300 Subject: [PATCH] [fix bug 1371258] Filter snippets based on vertical screen resolution. --- snippets/base/admin.py | 1 + snippets/base/fields.py | 17 ++++++++++ snippets/base/forms.py | 9 ++++++ .../migrations/0017_auto_20170609_1246.py | 31 +++++++++++++++++++ snippets/base/models.py | 1 + .../base/templates/base/includes/snippet.js | 18 +++++++++++ 6 files changed, 77 insertions(+) create mode 100644 snippets/base/migrations/0017_auto_20170609_1246.py diff --git a/snippets/base/admin.py b/snippets/base/admin.py index d84830edc..d1e481788 100644 --- a/snippets/base/admin.py +++ b/snippets/base/admin.py @@ -183,6 +183,7 @@ class SnippetAdmin(BaseSnippetAdmin): 'client_option_has_fxaccount', 'client_option_has_testpilot', 'client_option_is_default_browser', + 'client_option_screen_resolutions', ) }), ('Country and Locale', { diff --git a/snippets/base/fields.py b/snippets/base/fields.py index acc995ae6..68dcf7b77 100644 --- a/snippets/base/fields.py +++ b/snippets/base/fields.py @@ -2,6 +2,7 @@ from django.core.exceptions import ValidationError from django.db import models +from django.forms import MultipleChoiceField class RegexField(models.CharField): @@ -13,6 +14,22 @@ def __init__(self, *args, **kwargs): return super(RegexField, self).__init__(*args, **myargs) +class MultipleChoiceFieldCSV(MultipleChoiceField): + # To be used with in snippets.base.forms.SnippetAdminForm and in + # combination with DynamicField. We don't directly save() this field in the + # database so get_prep_value has not been implemented. + + def prepare_value(self, value): + value = super(MultipleChoiceFieldCSV, self).prepare_value(value) + if not isinstance(value, list): + value = value.split(';') + return value + + def clean(self, value): + value = super(MultipleChoiceFieldCSV, self).clean(value) + return ';'.join(value) + + def validate_regex(regex_str): if regex_str.startswith('/'): try: diff --git a/snippets/base/forms.py b/snippets/base/forms.py index 5a9fe295d..baaf5c007 100644 --- a/snippets/base/forms.py +++ b/snippets/base/forms.py @@ -11,6 +11,7 @@ from product_details import product_details from product_details.version_compare import Version, version_list +from snippets.base.fields import MultipleChoiceFieldCSV from snippets.base.models import (JSONSnippet, Snippet, SnippetTemplate, SnippetTemplateVariable, UploadedFile) @@ -146,6 +147,14 @@ class SnippetAdminForm(BaseSnippetAdminForm): choices=(('any', 'Show to all users'), ('yes', 'Show only to users with Firefox as default browser'), ('no', 'Show only to users with Firefox as second browser'))) + client_option_screen_resolutions = MultipleChoiceFieldCSV( + label='Show on screens', + help_text='Select all the screen resolutions you want this snippet to appear on.', + widget=forms.CheckboxSelectMultiple(), + initial=['0-1024', '1024-1920', '1920-50000'], # Show to all screens by default + choices=(('0-1024', 'Screens with less than 1024 vertical pixels. (low)'), + ('1024-1920', 'Screens with less than 1920 vertical pixels. (hd)'), + ('1920-50000', 'Screens with more than 1920 vertical pixels (full-hd, 4k)'))) def __init__(self, *args, **kwargs): super(SnippetAdminForm, self).__init__(*args, **kwargs) diff --git a/snippets/base/migrations/0017_auto_20170609_1246.py b/snippets/base/migrations/0017_auto_20170609_1246.py new file mode 100644 index 000000000..4451ddd1c --- /dev/null +++ b/snippets/base/migrations/0017_auto_20170609_1246.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + +from django_mysql.models.functions import AsType, ColumnAdd + + +def set_default_resolutions(apps, schema_editor): + Snippet = apps.get_model('base', 'Snippet') + resolutions = '0-1024;1024-1920;1920-50000' + Snippet.objects.update( + client_options=ColumnAdd('client_options', + {'screen_resolutions': AsType(resolutions, 'CHAR')}) + ) + + +def noop(apps, schema_editor): + # nothing needed to go back in time. + pass + + +class Migration(migrations.Migration): + + dependencies = [ + ('base', '0016_auto_20160419_1316'), + ] + + operations = [ + migrations.RunPython(set_default_resolutions, noop), + ] diff --git a/snippets/base/models.py b/snippets/base/models.py index 6f6f75183..a51a18ef1 100644 --- a/snippets/base/models.py +++ b/snippets/base/models.py @@ -405,6 +405,7 @@ class Snippet(CachingMixin, SnippetBaseModel): 'has_fxaccount': unicode, 'has_testpilot': unicode, 'is_default_browser': unicode, + 'screen_resolutions': unicode, } ) diff --git a/snippets/base/templates/base/includes/snippet.js b/snippets/base/templates/base/includes/snippet.js index 8af6e9385..3bdc29476 100644 --- a/snippets/base/templates/base/includes/snippet.js +++ b/snippets/base/templates/base/includes/snippet.js @@ -336,6 +336,24 @@ Mozilla.UITour.setConfiguration = function(configName, configValue) { }); } + // Filter based on screen resolution + var verticalScreenResolution = screen.width; + snippets = snippets.filter( + function(snippet) { + let snippetResolutions = snippet.client_options.screen_resolutions.split(';'); + let display = false; + snippetResolutions.forEach(function(resolution) { + let minmax = resolution.split('-'); + if (parseInt(minmax[0]) <= verticalScreenResolution + && verticalScreenResolution < parseInt(minmax[1])) { + display = true; + return; + } + }); + return display; + } + ); + // Exclude snippets in block list. var blockList = getBlockList(); snippets = snippets.filter(