Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • hansegucker/AlekSIS-Core
  • pinguin/AlekSIS-Core
  • AlekSIS/official/AlekSIS-Core
  • sunweaver/AlekSIS-Core
  • sggua/AlekSIS-Core
  • edward/AlekSIS-Core
  • magicfelix/AlekSIS-Core
7 results
Show changes
Commits on Source (2)
......@@ -6,6 +6,19 @@ All notable changes to this project will be documented in this file.
The format is based on `Keep a Changelog`_,
and this project adheres to `Semantic Versioning`_.
Unreleased
----------
Changed
~~~~~~~
* Use own templates and views for PWA meta and manifest.
Removed
~~~~~~~
* Drop django-pwa completely.
`2.0b0`_ - 2021-05-21
---------------------
......
......@@ -5,13 +5,7 @@ from django.utils.translation import gettext_lazy as _
from dynaconf import LazySettings
from .util.core_helpers import (
get_app_packages,
lazy_get_favicons,
lazy_preference,
merge_app_settings,
monkey_patch,
)
from .util.core_helpers import get_app_packages, merge_app_settings, monkey_patch
monkey_patch()
......@@ -130,7 +124,6 @@ INSTALLED_APPS = [
"impersonate",
"two_factor",
"material",
"pwa",
"ckeditor",
"ckeditor_uploader",
"django_js_reverse",
......@@ -652,29 +645,14 @@ DEFAULT_FAVICON_PATHS = {
"pwa_icon": os.path.join(STATIC_ROOT, "img/aleksis-icon.png"),
"favicon": os.path.join(STATIC_ROOT, "img/aleksis-icon.png"),
}
PWA_APP_NAME = lazy_preference("general", "title")
PWA_APP_DESCRIPTION = lazy_preference("general", "description")
PWA_APP_THEME_COLOR = lazy_preference("theme", "primary")
PWA_APP_BACKGROUND_COLOR = "#ffffff"
PWA_APP_DISPLAY = "standalone"
PWA_APP_ORIENTATION = "any"
PWA_APP_ICONS = lazy_get_favicons(
"pwa_icon", default=DEFAULT_FAVICON_PATHS["pwa_icon"], config={"android": [192, 512]}
)
PWA_APP_ICONS_APPLE = lazy_get_favicons(
"pwa_icon", default=DEFAULT_FAVICON_PATHS["pwa_icon"], config={"apple": [76, 114, 152, 180]}
)
PWA_APP_SPLASH_SCREEN = lazy_get_favicons(
"pwa_icon",
default=DEFAULT_FAVICON_PATHS["pwa_icon"],
config={"apple": [192]},
add_attrs={
"media": "(device-width: 320px) and (device-height: 568px) and"
"(-webkit-device-pixel-ratio: 2)"
},
)
PWA_ICONS_CONFIG = {
"android": [192, 512],
"apple": [76, 114, 152, 180],
"apple_splash": [192],
"microsoft": [144],
}
PWA_SERVICE_WORKER_PATH = os.path.join(STATIC_ROOT, "js", "serviceworker.js")
SERVICE_WORKER_PATH = os.path.join(STATIC_ROOT, "js", "serviceworker.js")
SITE_ID = 1
......
......@@ -112,6 +112,18 @@ $(document).ready(function () {
var el = $(e.target).parent();
el.addClass("closed").removeClass("opened");
});
// Initialize the service worker
if ('serviceWorker' in navigator) {
console.debug("Start registration of service worker.");
navigator.serviceWorker.register('/serviceworker.js', {
scope: '/'
}).then(function() {
console.debug("Service worker has been registered.");
}).catch(function() {
console.debug("Service worker registration has failed.")
});
}
});
// Show notice if serviceworker broadcasts that the current page comes from its cache
......
{# -*- engine:django -*- #}
{% load i18n menu_generator static sass_tags any_js pwa rules %}
{% load i18n menu_generator static sass_tags any_js rules %}
{% get_current_language as LANGUAGE_CODE %}
......
{% load pwa favtags %}
{% load favtags %}
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
......@@ -6,5 +6,31 @@
<meta name="description" content="{{ request.site.preferences.general__description }}"/>
<meta name="generator" content="AlekSIS School Information System"/>
<meta name="theme-color" content="red">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-title" content="{{ request.site.preferences.general__title }}">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="default">
<meta name="msapplication-navbutton-color" content="{{ request.site.preferences.theme__primary }}">
<meta name="msapplication-TileColor" content="{{ request.site.preferences.theme__primary }}">
<meta name="msapplication-TileImage" content="{{ PWA_ICONS.microsoft.144.faviconImage.url }}">
<meta name="application-name" content="{{ request.site.preferences.general__title }}">
<meta name="msapplication-starturl" content="/">
<meta name="msapplication-tap-highlight" content="no">
<meta name="browsermode" content="application">
<link href="/manifest.json" rel="manifest">
{% place_favicon %}
{% progressive_web_app_meta %}
{% for icon in PWA_ICONS.apple.values %}
<link rel="apple-touch-icon" href="{{ icon.faviconImage.url }}" sizes="{{ icon.size }}x{{ icon.size }}">
{% endfor %}
{% with icon=PWA_ICONS.apple_splash.192 %}
<link href="{{ icon.faviconImage.url }}" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image"/>
{% endwith %}
......@@ -18,8 +18,10 @@ from . import views
urlpatterns = [
path("", include("django_prometheus.urls")),
path("", include("pwa.urls"), name="pwa"),
path(settings.MEDIA_URL.removeprefix("/"), include("titofisto.urls")),
path("manifest.json", views.ManifestView.as_view(), name="manifest"),
path("serviceworker.js", views.ServiceWorkerView.as_view(), name="service_worker"),
path("offline/", views.OfflineView.as_view(), name="offline"),
path("about/", views.about, name="about_aleksis"),
path("accounts/logout/", auth_views.LogoutView.as_view(), name="logout"),
path(
......
......@@ -158,30 +158,12 @@ def get_or_create_favicon(title: str, default: str, is_favicon: bool = False) ->
return favicon
def lazy_get_favicons(
title: str,
config: dict[str, list[int]],
default: str,
add_attrs: Optional[dict[str, Any]] = None,
) -> Callable[[], list[dict[str, str]]]:
"""Lazily load a dictionary for PWA settings from favicon generation rules."""
if add_attrs is None:
add_attrs = {}
def _get_favicons() -> list[dict[str, str]]:
favicon = get_or_create_favicon(title, default)
favicon_imgs = favicon.get_favicons(config_override=config)
return [
{
"src": favicon_img.faviconImage.url,
"sizes": [f"{favicon_img.size}x{favicon_img.size}"],
}
| add_attrs
for favicon_img in favicon_imgs
]
def get_pwa_icons():
from django.conf import settings # noqa
return lazy(_get_favicons, list)()
favicon = get_or_create_favicon("pwa_icon", settings.DEFAULT_FAVICON_PATHS["pwa_icon"])
favicon_imgs = favicon.get_favicons(config_override=settings.PWA_ICONS_CONFIG)
return favicon_imgs
def is_impersonate(request: HttpRequest) -> bool:
......@@ -220,6 +202,12 @@ def custom_information_processor(request: HttpRequest) -> dict:
"""Provide custom information in all templates."""
from ..models import CustomMenu
pwa_icons = get_pwa_icons()
regrouped_pwa_icons = {}
for pwa_icon in pwa_icons:
regrouped_pwa_icons.setdefault(pwa_icon.rel, {})
regrouped_pwa_icons[pwa_icon.rel][pwa_icon.size] = pwa_icon
return {
"FOOTER_MENU": CustomMenu.get_default("footer"),
"ALTERNATIVE_LOGIN_VIEWS_LIST": [
......@@ -231,6 +219,7 @@ def custom_information_processor(request: HttpRequest) -> dict:
a for a in settings.ALTERNATIVE_LOGIN_VIEWS if a[0] in settings.AUTHENTICATION_BACKENDS
],
"ADMINS": settings.ADMINS,
"PWA_ICONS": regrouped_pwa_icons,
}
......
......@@ -13,10 +13,13 @@ from django.http import (
HttpResponse,
HttpResponseNotFound,
HttpResponseRedirect,
JsonResponse,
)
from django.http.response import FileResponse
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse, reverse_lazy
from django.utils.decorators import method_decorator
from django.utils.translation import get_language
from django.utils.translation import gettext_lazy as _
from django.views.decorators.cache import never_cache
from django.views.generic.base import TemplateView, View
......@@ -96,6 +99,7 @@ from .util.apps import AppConfig
from .util.celery_progress import render_progress_page
from .util.core_helpers import (
get_allowed_object_ids,
get_pwa_icons,
get_site_preferences,
has_person,
objectgetter_optional,
......@@ -115,6 +119,56 @@ class RenderPDFView(TemplateView):
return render_pdf(request, self.template_name, context)
class ServiceWorkerView(View):
"""Render serviceworker.js under root URL.
This can't be done by static files,
because the PWA has a scope and
only accepts service worker files from the root URL.
"""
def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
return FileResponse(open(settings.SERVICE_WORKER_PATH))
class ManifestView(View):
"""Build manifest.json for PWA."""
def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
prefs = get_site_preferences()
pwa_imgs = get_pwa_icons()
icons = [
{
"src": favicon_img.faviconImage.url,
"sizes": f"{favicon_img.size}x{favicon_img.size}",
}
for favicon_img in pwa_imgs
]
manifest = {
"name": prefs["general__title"],
"short_name": prefs["general__title"],
"description": prefs["general__description"],
"start_url": "/",
"scope": "/",
"lang": get_language(),
"display": "standalone",
"orientation": "any",
"status_bar": "default",
"background_color": "#ffffff",
"theme_color": prefs["theme__primary"],
"icons": icons,
}
return JsonResponse(manifest)
class OfflineView(TemplateView):
"""Show an error page if there is no internet connection."""
template_name = "offline.html"
@permission_required("core.view_dashboard_rule")
def index(request: HttpRequest) -> HttpResponse:
"""View for dashboard."""
......
This diff is collapsed.
......@@ -67,7 +67,6 @@ django_select2 = "^7.1"
django-two-factor-auth = { version = "^1.12.1", extras = [ "yubikey", "phonenumbers", "call", "sms" ] }
django-yarnpkg = "^6.0"
django-material = "^1.6.0"
django-pwa = "^1.0.8"
django-dynamic-preferences = "^1.9"
django_widget_tweaks = "^1.4.5"
django-filter = "^2.2.0"
......