Mercurial > sat_legacy_website
changeset 29:b45621706d83
use Bootstrap carousels to display images and videos galeries:
- one carousel for a 3x3 thumbnails grid
- a second one in a modal window to view bigger pictures when a thumbnail is clicked
author | souliane <souliane@mailoo.org> |
---|---|
date | Wed, 21 Jan 2015 20:13:19 +0100 |
parents | 30a1edf90fae |
children | 565d653a15d3 |
files | README sat_website/screenshots.py sat_website/templatetags/partition.py sat_website/templatetags/utils.py sat_website/views.py static/css/sat_website.css static/js/sat_website.js templates/sat_website/base.html templates/sat_website/gallery.html templates/sat_website/screenshots.html templates/sat_website/screenshots_tech.html |
diffstat | 11 files changed, 252 insertions(+), 241 deletions(-) [+] |
line wrap: on
line diff
--- a/README Wed Jan 21 20:08:26 2015 +0100 +++ b/README Wed Jan 21 20:13:19 2015 +0100 @@ -75,7 +75,6 @@ - Bootstrap v3.3.1 (http://getbootstrap.com) | Copyright 2011-2014 Twitter, Inc. | MIT licence: https://github.com/twbs/bootstrap/blob/master/LICENSE - jQuery v1.11.1 (http://jquery.org) | Copyright 2005-2014 jQuery Foundation, Inc. | MIT licence: jquery.org/license - - Partition (http://djangosnippets.org/snippets/401/) | Copyright 2007 Smiley Chris | Custom free (libre) licence: http://djangosnippets.org/about/tos In addition, this project use Django to run.
--- a/sat_website/screenshots.py Wed Jan 21 20:08:26 2015 +0100 +++ b/sat_website/screenshots.py Wed Jan 21 20:13:19 2015 +0100 @@ -23,7 +23,7 @@ from collections import namedtuple ImageDesc = namedtuple("ImageDesc","path description") -VideoDesc = namedtuple("VideoDesc","path description poster") +VideoDesc = namedtuple("VideoDesc", "path description poster lang subtitles") #list the pictures @@ -33,16 +33,16 @@ ImageDesc("images/screenshots/primitivus/primitivus_tarot.png", _(u"Primitivus showing a french Tarot play")), ImageDesc("images/screenshots/jp/jp.png", _(u"cowsay sent in conversation through jp")), ImageDesc("images/screenshots/wix/wix_tarot.png", _(u"Wix showing a french Tarot play")), + VideoDesc("videos/screencasts/présentation_SàT.webm", _(u"The first video show wix, primitivus and jp"), "videos/screencasts/posters/présentation_SàT.jpg", 'fr', ''), + VideoDesc("videos/screencasts/présentation_SàT_2.webm", _(u"This video show french Tarot game, and how to use Thunderbird with SàT"), "videos/screencasts/posters/présentation_SàT_2.jpg", 'fr', ''), + VideoDesc("videos/screencasts/présentation_SàT_3.webm", _(u"This video focuses on Libervia. The UI is really outdated, but we can see some features"), "videos/screencasts/posters/présentation_SàT_3.jpg", 'fr', ''), + VideoDesc("videos/screencasts/présentation_SàT_5_radio_collective.webm", _(u"Demo of the new Libervia UI, and of the collective radio feature"), "videos/screencasts/posters/radiocol.jpg", 'fr', ''), ] -screencasts = [ - VideoDesc("videos/screencasts/présentation_SàT.webm", _(u"The first video show wix, primitivus and jp"), "videos/screencasts/posters/présentation_SàT.jpg"), - VideoDesc("videos/screencasts/présentation_SàT_2.webm", _(u"This video show french Tarot game, and how to use Thunderbird with SàT"), "videos/screencasts/posters/présentation_SàT_2.jpg"), - VideoDesc("videos/screencasts/présentation_SàT_3.webm", _(u"This video focuses on Libervia. The UI is really outdated, but we can see some features"), "videos/screencasts/posters/présentation_SàT_3.jpg"), - VideoDesc("videos/screencasts/présentation_SàT_4_copie_et_pipe.webm", _(u"How to copy and pipe streams over XMPP"), "videos/screencasts/posters/présentation_SàT_4.jpg"), - VideoDesc("videos/screencasts/présentation_SàT_5_radio_collective.webm", _(u"Demo of the new Libervia UI, and of the collective radio feature"), "videos/screencasts/posters/radiocol.jpg"), - VideoDesc("videos/screencasts/présentation_SàT_6_export_commande.webm", _(u"Exporting a command: an FTP client is exported to a Gajim contact"), "videos/screencasts/posters/présentation_SàT_6_export_commande.jpg"), - VideoDesc("videos/screencasts/présentation_SàT_7_télécommande_universelle.webm", _(u"Use ad-hoc commands to control a VLC player from Libervia"), "videos/screencasts/posters/présentation_SàT_7_télécommande_universelle.png"), +screenshots_tech = [ + VideoDesc("videos/screencasts/présentation_SàT_7_télécommande_universelle.webm", _(u"Use ad-hoc commands to control a VLC player from Libervia"), "videos/screencasts/posters/présentation_SàT_7_télécommande_universelle.png", 'fr', ''), + VideoDesc("videos/screencasts/présentation_SàT_6_export_commande.webm", _(u"Exporting a command: an FTP client is exported to a Gajim contact"), "videos/screencasts/posters/présentation_SàT_6_export_commande.jpg", 'fr', ''), + VideoDesc("videos/screencasts/présentation_SàT_4_copie_et_pipe.webm", _(u"How to copy and pipe streams over XMPP"), "videos/screencasts/posters/présentation_SàT_4.jpg", 'fr', ''), ]
--- a/sat_website/templatetags/partition.py Wed Jan 21 20:08:26 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,166 +0,0 @@ -""" -(c) Smiley Chris 2007 - -This code comes from Django snippets ( http://djangosnippets.org/snippets/401/ ) -According to the Terms of Service ( http://djangosnippets.org/about/tos/ ), the code can be freely used - -Template filters to partition lists into rows or columns. - -A common use-case is for splitting a list into a table with columns:: - - {% load partition %} - <table> - {% for row in mylist|columns:3 %} - <tr> - {% for item in row %} - <td>{{ item }}</td> - {% endfor %} - </tr> - {% endfor %} - </table> -""" - -from django.template import Library - -register = Library() - -def rows(thelist, n): - """ - Break a list into ``n`` rows, filling up each row to the maximum equal - length possible. For example:: - - >>> l = range(10) - - >>> rows(l, 2) - [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]] - - >>> rows(l, 3) - [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9]] - - >>> rows(l, 4) - [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]] - - >>> rows(l, 5) - [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9]] - - >>> rows(l, 9) - [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9], [], [], [], []] - - # This filter will always return `n` rows, even if some are empty: - >>> rows(range(2), 3) - [[0], [1], []] - """ - try: - n = int(n) - thelist = list(thelist) - except (ValueError, TypeError): - return [thelist] - list_len = len(thelist) - split = list_len // n - - if list_len % n != 0: - split += 1 - return [thelist[split*i:split*(i+1)] for i in range(n)] - -def rows_distributed(thelist, n): - """ - Break a list into ``n`` rows, distributing columns as evenly as possible - across the rows. For example:: - - >>> l = range(10) - - >>> rows_distributed(l, 2) - [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]] - - >>> rows_distributed(l, 3) - [[0, 1, 2, 3], [4, 5, 6], [7, 8, 9]] - - >>> rows_distributed(l, 4) - [[0, 1, 2], [3, 4, 5], [6, 7], [8, 9]] - - >>> rows_distributed(l, 5) - [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9]] - - >>> rows_distributed(l, 9) - [[0, 1], [2], [3], [4], [5], [6], [7], [8], [9]] - - # This filter will always return `n` rows, even if some are empty: - >>> rows(range(2), 3) - [[0], [1], []] - """ - try: - n = int(n) - thelist = list(thelist) - except (ValueError, TypeError): - return [thelist] - list_len = len(thelist) - split = list_len // n - - remainder = list_len % n - offset = 0 - rows = [] - for i in range(n): - if remainder: - start, end = (split+1)*i, (split+1)*(i+1) - else: - start, end = split*i+offset, split*(i+1)+offset - rows.append(thelist[start:end]) - if remainder: - remainder -= 1 - offset += 1 - return rows - -def columns(thelist, n): - """ - Break a list into ``n`` columns, filling up each column to the maximum equal - length possible. For example:: - - >>> from pprint import pprint - >>> for i in range(7, 11): - ... print '%sx%s:' % (i, 3) - ... pprint(columns(range(i), 3), width=20) - 7x3: - [[0, 3, 6], - [1, 4], - [2, 5]] - 8x3: - [[0, 3, 6], - [1, 4, 7], - [2, 5]] - 9x3: - [[0, 3, 6], - [1, 4, 7], - [2, 5, 8]] - 10x3: - [[0, 4, 8], - [1, 5, 9], - [2, 6], - [3, 7]] - - # Note that this filter does not guarantee that `n` columns will be - # present: - >>> pprint(columns(range(4), 3), width=10) - [[0, 2], - [1, 3]] - """ - try: - n = int(n) - thelist = list(thelist) - except (ValueError, TypeError): - return [thelist] - list_len = len(thelist) - split = list_len // n - if list_len % n != 0: - split += 1 - return [thelist[i::split] for i in range(split)] - -register.filter(rows) -register.filter(rows_distributed) -register.filter(columns) - -def _test(): - import doctest - doctest.testmod() - -if __name__ == "__main__": - _test()
--- a/sat_website/templatetags/utils.py Wed Jan 21 20:08:26 2015 +0100 +++ b/sat_website/templatetags/utils.py Wed Jan 21 20:13:19 2015 +0100 @@ -12,3 +12,27 @@ # rely on a strange comparison - isinstance(value, arg) doesn't work here return type(value) == tuple +@register.filter +def buffer(value, n): + """Split values in sub-lists of n elements. + + @param value (list): a list object + @return: a list containing sub-lists + + For example: + + >>> buffer(range(10), 2) + [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9]] + + >>> buffer(range(10), 3) + [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]] + + >>> buffer(range(10), 4) + [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9]] + """ + result = [] + index = 0 + while index < len(value): + result.append(value[index:index + n]) + index += n + return result
--- a/sat_website/views.py Wed Jan 21 20:08:26 2015 +0100 +++ b/sat_website/views.py Wed Jan 21 20:13:19 2015 +0100 @@ -71,10 +71,8 @@ return render_to_response('sat_website/overview.html', context) elif category == "screenshots": context["screenshots"] = screenshots.screenshots - context["screencasts"] = screenshots.screencasts elif category == "screenshots_tech": - context["screenshots"] = screenshots.screencasts - context["screencasts"] = screenshots.screencasts + context["screenshots"] = screenshots.screenshots_tech elif category == "social_contract": context["SOCIAL_CONTRACT"] = social_contract.get_social_contract()
--- a/static/css/sat_website.css Wed Jan 21 20:08:26 2015 +0100 +++ b/static/css/sat_website.css Wed Jan 21 20:13:19 2015 +0100 @@ -36,13 +36,54 @@ font-size: 13px; } +.carousel-inner { + padding: 10px 30px 10px 30px; + border-radius: 5px; +} + +.carousel-inner > .item { + text-align: center; +} + +.carousel-caption { + padding: 10px; + bottom: -55px; + color: black; + font-style: italic; + font-size: 14px; + text-shadow: none; +} + +.carousel-indicators { + bottom: -5px; + color: black; +} + +.carousel-indicators li { + border: 1px solid black; +} + +.carousel-indicators .active { + background-color: black; +} + +.carousel-control.left, .carousel-control.right{ + width: 30px; + border-radius: 5px; +} + +.modal-header .close { + margin-top: -10px; + padding-right: 5px; +} + /* sat_website own styles */ #language { - /* position: absolute; */ text-align: center; + padding-top: 10px; } #sat_logo { @@ -96,25 +137,28 @@ } div:last-child>div.feature { - /* we don't wine line on the last feature */ + /* we don't want the line on the last feature */ border-bottom-style: none; } -.screenshot_desc { - text-align: center; - font-style: italic; - font-size: 14px; +#carousel-screenshots img, #carousel-screenshots video { + cursor: pointer; + height: 200px; + width: auto; + display: table-cell; } -.screencast { - text-align: center; +#modal-screenshots .modal-dialog { + max-width: 90%; + width: auto; } -.screencast_dest { - text-align: center; - font-style: italic; - font-size: 14px; - margin-bottom: 30px; +#carousel-screenshots-modal .carousel-inner { + padding-bottom: 80px; +} + +#carousel-screenshots-modal img, #carousel-screenshots-modal video { + margin: auto; } #language_form {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/static/js/sat_website.js Wed Jan 21 20:13:19 2015 +0100 @@ -0,0 +1,24 @@ +$(document).ready(function() { + + // language selector + $('#language_select').change(function() { + $('#language_form').submit(); + }); + + // open the big gallery when a thumbnail is clicked + $('#carousel-screenshots .thumbnail').click(function() { + $('#modal-screenshots').modal('show'); + index = parseInt($(this).attr('index')); + $('#carousel-screenshots-modal').carousel(index); + // start playing the big video + if ($(this)[0].tagName == 'VIDEO') { + $('#carousel-screenshots-modal img, #carousel-screenshots-modal video')[index].play(); + } + }); + + // thumbail's video starts playing when clicked, pause it + $('#carousel-screenshots video.thumbnail').each(function(index) { + $(this).on('play', function(e) { $(this)[0].pause(); }); + }); + +});
--- a/templates/sat_website/base.html Wed Jan 21 20:08:26 2015 +0100 +++ b/templates/sat_website/base.html Wed Jan 21 20:13:19 2015 +0100 @@ -58,12 +58,6 @@ {% block content %}{% endblock %} <script src="{% static "js/jquery.min.js" %}"></script> <script src="{% static "bootstrap/js/bootstrap.min.js" %}"></script> - <script type="text/javascript"> - $(document).ready(function() { - $('#language_select').change(function() { - $('#language_form').submit(); - }); - }); - </script> + <script src="{% static "js/sat_website.js" %}"></script> </body> </html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/sat_website/gallery.html Wed Jan 21 20:13:19 2015 +0100 @@ -0,0 +1,105 @@ +{% comment %} +SàT website: Salut à Toi's presentation website +Copyright (C) 2012 Jérôme Poisson (goffi@goffi.org) + +This file is part of SàT website. + +SàT website is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Foobar is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Foobar. If not, see <http://www.gnu.org/licenses/>. +{% endcomment %} + +{% load i18n %} +{% load staticfiles %} +{% load utils %} + +<div id="carousel-screenshots" class="carousel slide" data-ride="carousel" data-interval="0"> + {% if screenshots|length > 9 %} + <ol class="carousel-indicators"> + {% for row in screenshots|buffer:9 %} + <li data-target="#carousel-screenshots" data-slide-to="{{ forloop.counter0 }}"{% if not forloop.counter0 %} class="active"{% endif %}></li> + {% endfor %} + </ol> + {% endif %} + <div class="carousel-inner" role="listbox"> + {% for row in screenshots|buffer:9 %} + <div class="item{% if not forloop.counter0 %} active{% endif %}"> + {% for screenshot in row %} + <div class="col-md-4"> + {% if screenshot.poster %} + <video index="{{ forloop.counter0 }}" class="thumbnail img-responsive" width="640" height="400" poster="{% static screenshot.poster %}" controls="controls" src="{% static screenshot.path %}" preload="none"> + {% blocktrans with firefox="<a href=\"http://www.mozilla-europe.org/fr/\">Firefox</a>" %}Your browser doesn't manage the « video » tag, you should update, e.g. with the last {{ firefox }}{% endblocktrans %} + </video> + {% else %} + <img index="{{ forloop.counter0 }}" class="thumbnail img-responsive" src="{% static screenshot.path %}"> + {% endif %} + </div> + {% endfor %} + </div> + {% endfor %} + {% if screenshots|length > 9 %} + <a class="left carousel-control" href="#carousel-screenshots" role="button" data-slide="prev"> + <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span> + <span class="sr-only">Previous</span> + </a> + <a class="right carousel-control" href="#carousel-screenshots" role="button" data-slide="next"> + <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span> + <span class="sr-only">Next</span> + </a> + {% endif %} + </div> +</div> + +<div class="modal" id="modal-screenshots" role="dialog"> + <div class="modal-dialog"> + <div class="modal-content"> + <div class="modal-header"> + <button class="close" type="button" data-dismiss="modal">×</button> + </div> + <div class="modal-body"> + <div id="carousel-screenshots-modal" class="carousel slide" data-ride="carousel" data-interval="0"> + {% if screenshots|length > 1 %} + <ol class="carousel-indicators"> + {% for screenshot in screenshots %} + <li data-target="#carousel-screenshots-modal" data-slide-to="{{ forloop.counter0 }}"{% if not forloop.counter0 %} class="active"{% endif %}></li> + {% endfor %} + </ol> + {% endif %} + <div class="carousel-inner" role="listbox"> + {% for screenshot in screenshots %} + <div class="item{% if not forloop.counter0 %} active{% endif %}"> + {% if screenshot.poster %} + <video class="img-responsive" width="640" height="400" poster="{% static screenshot.poster %}" controls="controls" src="{% static screenshot.path %}" preload="none"> + {% blocktrans with firefox="<a href=\"http://www.mozilla-europe.org/fr/\">Firefox</a>" %}Your browser doesn't manage the « video » tag, you should update, e.g. with the last {{ firefox }}{% endblocktrans %} + </video> + {% else %} + <img class="img-responsive" src="{% static screenshot.path %}"> + {% endif %} + <div class="carousel-caption">{{ screenshot.description }}</div> + </div> + {% endfor %} + </div> + {% if screenshots|length > 1 %} + <a class="left carousel-control" href="#carousel-screenshots-modal" data-slide="prev"> + <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span> + <span class="sr-only">Previous</span> + </a> + <a class="right carousel-control" href="#carousel-screenshots-modal" data-slide="next"> + <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span> + <span class="sr-only">Next</span> + </a> + {% endif %} + </div> + </div> + </div> + </div> +</div>
--- a/templates/sat_website/screenshots.html Wed Jan 21 20:08:26 2015 +0100 +++ b/templates/sat_website/screenshots.html Wed Jan 21 20:13:19 2015 +0100 @@ -21,47 +21,8 @@ {% endcomment %} {% load i18n %} -{% load staticfiles %} -{% load partition %} - -{% block headline %}{% trans "Some screenshots..." %}{% endblock %} -{% block extra %} - <div class="btn-group"> - <a class="btn btn-default btn-info" href="#screenshots">{% trans "screenshots" %}</a> - <a class="btn btn-default btn-primary" href="#screencasts">{% trans "screencasts" %}</a> - </div> -{% endblock %} +{% block headline %}{% trans "Screenshots and videos..." %}{% endblock %} {% block main_container %} -<a name="screenshots"><h3>{% trans "Screenshots" %}</h3></a> - <div class="row"> - {% for row in screenshots|columns:3 %} - {% for screenshot in row %} - <div class="col-md-4"> - <a href="{% static screenshot.path %}" class="thumbnail"> - <img src="{% static screenshot.path %}" alt="{{ screenshot.description }}"> - </a> - <div class="screenshot_desc"> - {{ screenshot.description }} - </div> - </div> - - {% endfor %} - </ul> - {% endfor %} - </div> -<a name="screencasts"><h3>{% trans "Screencasts" %}</h3></a> - {% for screencast in screencasts %} - <div class="row"> - <div class="col-md-10 col-md-offset-1"> - <div class="screencast"> - <video width="640" height="400" poster="{% static screencast.poster %}" controls="controls" src="{% static screencast.path %}" preload="none"> - {% blocktrans with firefox="<a href=\"http://www.mozilla-europe.org/fr/\">Firefox</a>" %}Your browser doesn't manage the « video » tag, you should update, e.g. with the last {{ firefox }}{% endblocktrans %} - </video> - </div> - <div class="screencast_dest"> - {{ screencast.description }} - </div> - </div> - </div> - {% endfor %} + +{% include "sat_website/gallery.html" %} {% endblock %}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/sat_website/screenshots_tech.html Wed Jan 21 20:13:19 2015 +0100 @@ -0,0 +1,28 @@ +{% extends "sat_website/category.html" %} + +{% comment %} +SàT website: Salut à Toi's presentation website +Copyright (C) 2012 Jérôme Poisson (goffi@goffi.org) + +This file is part of SàT website. + +SàT website is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Foobar is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with Foobar. If not, see <http://www.gnu.org/licenses/>. +{% endcomment %} + +{% load i18n %} +{% block headline %}{% trans "Technical screenshots and videos..." %}{% endblock %} +{% block main_container %} + +{% include "sat_website/gallery.html" %} +{% endblock %}