pwa: add possibility to set application icon (#29457)
This commit is contained in:
parent
2d4ca51241
commit
2e58ce9b02
|
@ -0,0 +1,20 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.12 on 2019-01-04 19:36
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('pwa', '0003_pwanavigationentry'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='pwasettings',
|
||||
name='application_icon',
|
||||
field=models.FileField(blank=True, help_text='Should be a square of at least 512\xd7512 pixels.', null=True, upload_to=b'pwa', verbose_name='Application Icon'),
|
||||
),
|
||||
]
|
|
@ -1,3 +1,5 @@
|
|||
# -*- coding: utf-8 -*
|
||||
#
|
||||
# combo - content management system
|
||||
# Copyright (C) 2015-2018 Entr'ouvert
|
||||
#
|
||||
|
@ -33,6 +35,13 @@ from combo import utils
|
|||
|
||||
|
||||
class PwaSettings(models.Model):
|
||||
APPLICATION_ICON_SIZES = ['%sx%s' % (x, x) for x in (48, 96, 192, 256, 512)]
|
||||
application_icon = models.FileField(
|
||||
verbose_name=_('Application Icon'),
|
||||
help_text=_(u'Should be a square of at least 512×512 pixels.'),
|
||||
upload_to='pwa',
|
||||
blank=True,
|
||||
null=True)
|
||||
offline_text = RichTextField(
|
||||
verbose_name=_('Offline Information Text'),
|
||||
default=_('You are currently offline.'),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% load static %}{
|
||||
{% load static thumbnail %}{
|
||||
"name": "{% firstof global_title "Compte Citoyen" %}",
|
||||
"short_name": "{% firstof global_title "Compte Citoyen" %}",
|
||||
"start_url": "{% firstof pwa_start_url "/" %}",
|
||||
|
@ -8,6 +8,17 @@
|
|||
{% endif %}
|
||||
{% block icons %}
|
||||
"icons": [
|
||||
{% if pwa_settings.application_icon %}
|
||||
{% for icon_size in pwa_settings.APPLICATION_ICON_SIZES %}
|
||||
{
|
||||
"sizes": "{{ icon_size }}",
|
||||
{% thumbnail pwa_settings.application_icon icon_size crop='center' format='PNG' as im %}
|
||||
"src": "{{ site_base }}{{ im.url }}",
|
||||
{% endthumbnail %}
|
||||
"type": "image/png"
|
||||
}{% if not forloop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% for icon_size in icon_sizes %}
|
||||
{
|
||||
"sizes": "{{ icon_size }}x{{ icon_size }}",
|
||||
|
@ -15,6 +26,7 @@
|
|||
"type": "image/png"
|
||||
}{% if not forloop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
],
|
||||
{% endblock %}
|
||||
{% block extra %}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% extends "combo/pwa/manager_base.html" %}
|
||||
{% load i18n static %}
|
||||
{% load i18n thumbnail %}
|
||||
|
||||
{% block content %}
|
||||
<div class="manager-mobile-home-layout">
|
||||
|
@ -9,7 +9,11 @@
|
|||
<div class="mobile-app-content">
|
||||
<div class="splash">
|
||||
<div class="appicon">
|
||||
<img src="{% static "" %}{{ css_variant }}/{{ icon_prefix }}{{icon_sizes|last}}px.png" alt="">
|
||||
{% if pwa_settings.application_icon %}
|
||||
{% thumbnail pwa_settings.application_icon '512x512' crop='center' format='PNG' as im %}
|
||||
<img src="{{ im.url }}" alt="">
|
||||
{% endthumbnail %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="applabel">{% firstof global_title "Compte Citoyen" %}</div>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% load i18n static %}<!DOCTYPE html>
|
||||
{% load i18n thumbnail %}<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
|
@ -42,7 +42,12 @@ p.retry a {
|
|||
</head>
|
||||
<body>
|
||||
<div class="info-text">
|
||||
<img src="{% static "" %}{{ css_variant }}/{{ icon_prefix }}{{icon_sizes|last}}px.png" alt="">
|
||||
{% if pwa_settings.application_icon %}
|
||||
{% thumbnail pwa_settings.application_icon '512x512' crop='center' format='PNG' as im %}
|
||||
<img src="{{ im.url }}" alt="">
|
||||
{% endthumbnail %}
|
||||
{% endif %}
|
||||
|
||||
{{ pwa_settings.offline_text|safe }}
|
||||
|
||||
{% if pwa_settings.offline_retry_button %}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% load combo gadjo static %}
|
||||
{% load combo gadjo static thumbnail %}
|
||||
|
||||
/* global self, caches, fetch, URL, Response */
|
||||
'use strict';
|
||||
|
@ -26,7 +26,11 @@ var config = {
|
|||
version: 'v{{ version }}',
|
||||
staticCacheItems: [
|
||||
'/__pwa__/offline/',
|
||||
'{% static "" %}{{ css_variant }}/{{ icon_prefix }}{{icon_sizes|last}}px.png'
|
||||
{% if pwa_settings.application_icon %}
|
||||
{% thumbnail pwa_settings.application_icon '512x512' crop='center' format='PNG' as im %}
|
||||
'{{ im.url }}'
|
||||
{% endthumbnail %}
|
||||
{% endif %}
|
||||
],
|
||||
cachePathPattern: /^\/static\/.*/,
|
||||
handleFetchPathPattern: /.*/,
|
||||
|
|
|
@ -32,7 +32,10 @@ def manifest_json(request, *args, **kwargs):
|
|||
template = get_template('combo/manifest.json')
|
||||
except TemplateDoesNotExist:
|
||||
raise Http404()
|
||||
return HttpResponse(template.render({}, request), content_type='application/json')
|
||||
context = {
|
||||
'site_base': request.build_absolute_uri('/')[:-1],
|
||||
}
|
||||
return HttpResponse(template.render(context, request), content_type='application/json')
|
||||
|
||||
|
||||
def js_response(request, template_name, **kwargs):
|
||||
|
@ -81,9 +84,4 @@ def subscribe_push(request, *args, **kwargs):
|
|||
class OfflinePage(TemplateView):
|
||||
template_name = 'combo/pwa/offline.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(OfflinePage, self).get_context_data(**kwargs)
|
||||
context['pwa_settings'] = PwaSettings.singleton()
|
||||
return context
|
||||
|
||||
offline_page = OfflinePage.as_view()
|
||||
|
|
|
@ -17,8 +17,12 @@
|
|||
|
||||
from django.conf import settings
|
||||
|
||||
from combo.utils.cache import cache_during_request
|
||||
from combo.apps.pwa.models import PwaSettings
|
||||
|
||||
def template_vars(request):
|
||||
context_extras = {}
|
||||
context_extras['debug'] = settings.DEBUG
|
||||
context_extras['pwa_settings'] = cache_during_request(PwaSettings.singleton)
|
||||
context_extras.update(settings.TEMPLATE_VARS)
|
||||
return context_extras
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import base64
|
||||
import os
|
||||
|
||||
import mock
|
||||
import pytest
|
||||
from webtest import Upload
|
||||
|
||||
try:
|
||||
import pywebpush
|
||||
|
@ -137,6 +139,14 @@ def test_pwa_manager(app, admin_user):
|
|||
resp = resp.form.submit()
|
||||
assert 'An URL cannot be specified' in resp.text
|
||||
|
||||
# add an icon
|
||||
resp = app.get('/manage/pwa/')
|
||||
resp.form['application_icon'] = Upload('test.png',
|
||||
base64.decodestring(b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAACklEQVQI12NoAAAAggCB3UNq9AAAAABJRU5ErkJggg=='),
|
||||
'image/png')
|
||||
resp = resp.form.submit().follow()
|
||||
assert PwaSettings.singleton().application_icon.name == 'pwa/test.png'
|
||||
|
||||
|
||||
def test_pwa_offline_page(app):
|
||||
PwaSettings.objects.all().delete()
|
||||
|
@ -175,3 +185,21 @@ def test_pwa_navigation_templatetag(app):
|
|||
|
||||
nav = t.render(Context({'request': request, 'render_skeleton': True}))
|
||||
assert 'data-pwa-user-name="{% block placeholder-user-name %}' in nav
|
||||
|
||||
|
||||
def test_pwa_application_icon(app, admin_user):
|
||||
app = login(app)
|
||||
with override_settings(TEMPLATE_VARS={'pwa_display': 'standalone'}):
|
||||
PwaSettings.objects.all().delete()
|
||||
resp = app.get('/manage/pwa/')
|
||||
resp.form['application_icon'] = Upload('test.png',
|
||||
base64.decodestring(b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAACklEQVQI12NoAAAAggCB3UNq9AAAAABJRU5ErkJggg=='),
|
||||
'image/png')
|
||||
resp = resp.form.submit().follow()
|
||||
|
||||
resp = app.get('/manifest.json', status=200)
|
||||
assert len(resp.json['icons']) == 5
|
||||
|
||||
# make sure largest icon is referenced in service worker
|
||||
resp2 = app.get('/service-worker.js', status=200)
|
||||
assert resp.json['icons'][-1]['src'].split('/')[-1] in resp.text
|
||||
|
|
Loading…
Reference in New Issue