Merge pull request #1401 from umap-project/favicon

Set a default favicon
This commit is contained in:
Yohan Boniface 2023-11-15 15:06:09 +01:00 committed by GitHub
commit 8d70edf931
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 54 additions and 4 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 638 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

View file

@ -0,0 +1,5 @@
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<rect x=".3" y=".3" width="15.5" height="15.5" rx="7.8" fill="#F2F2F2" stroke="#F2F2F2" stroke-width=".5"/>
<path d="M5.9 3.5A5 5 0 0 0 8 13C4.1 9.4 3.2 5 5.9 3.5ZM8 13a5 5 0 0 0 2.1-9.5C12.8 4.9 12 9.4 8 13Z" fill="#323E56"/>
<path d="M9.9 5.6a1.9 1.9 0 1 1-3.8 0 1.9 1.9 0 0 1 3.8 0Z" fill="#323E56"/>
</svg>

After

Width:  |  Height:  |  Size: 390 B

View file

@ -15,6 +15,11 @@
{% endblock extra_head %} {% endblock extra_head %}
<meta name="viewport" <meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
{# See https://evilmartians.com/chronicles/how-to-favicon-in-2021-six-files-that-fit-most-needs #}
<link rel="icon" href="{{ STATIC_URL }}umap/favicons/favicon.ico" sizes="32x32">
<link rel="icon" href="{{ STATIC_URL }}umap/favicons/icon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="{{ STATIC_URL }}umap/favicons/apple-touch-icon.png"><!-- 180×180 -->
<link rel="manifest" href="/manifest.webmanifest">
</head> </head>
<body class="{% block body_class %}{% endblock body_class %}"> <body class="{% block body_class %}{% endblock body_class %}">
{% block header %} {% block header %}

View file

@ -5,9 +5,11 @@ from django.conf.urls.static import static
from django.contrib import admin from django.contrib import admin
from django.contrib.auth import views as auth_views from django.contrib.auth import views as auth_views
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.contrib.staticfiles.storage import staticfiles_storage
from django.contrib.staticfiles.urls import staticfiles_urlpatterns from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.views.decorators.cache import cache_control, cache_page, never_cache from django.views.decorators.cache import cache_control, cache_page, never_cache
from django.views.decorators.csrf import ensure_csrf_cookie from django.views.decorators.csrf import ensure_csrf_cookie
from django.views.generic.base import RedirectView
from . import views from . import views
from .decorators import ( from .decorators import (
@ -183,7 +185,23 @@ urlpatterns += i18n_patterns(
re_path(r"^user/(?P<identifier>.+)/$", views.user_maps, name="user_maps"), re_path(r"^user/(?P<identifier>.+)/$", views.user_maps, name="user_maps"),
re_path(r"", include(i18n_urls)), re_path(r"", include(i18n_urls)),
) )
urlpatterns += (path("stats/", cache_page(60 * 60)(views.stats), name="stats"),) urlpatterns += (
path("stats/", cache_page(60 * 60)(views.stats), name="stats"),
path(
"favicon.ico",
cache_control(max_age=60 * 60 * 24, immutable=True, public=True)(
RedirectView.as_view(
url=staticfiles_storage.url("umap/favicons/favicon.ico")
)
),
),
path(
"manifest.webmanifest",
cache_control(max_age=60 * 60 * 24, immutable=True, public=True)(
views.webmanifest
),
),
)
if settings.DEBUG and settings.MEDIA_ROOT: if settings.DEBUG and settings.MEDIA_ROOT:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

View file

@ -15,6 +15,7 @@ from django.contrib.auth import logout as do_logout
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.gis.measure import D from django.contrib.gis.measure import D
from django.contrib.postgres.search import SearchQuery, SearchVector from django.contrib.postgres.search import SearchQuery, SearchVector
from django.contrib.staticfiles.storage import staticfiles_storage
from django.core.mail import send_mail from django.core.mail import send_mail
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from django.core.signing import BadSignature, Signer from django.core.signing import BadSignature, Signer
@ -34,6 +35,8 @@ from django.utils.encoding import smart_bytes
from django.utils.http import http_date from django.utils.http import http_date
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django.utils.translation import to_locale from django.utils.translation import to_locale
from django.views.decorators.cache import cache_control
from django.views.decorators.http import require_GET
from django.views.generic import DetailView, TemplateView, View from django.views.generic import DetailView, TemplateView, View
from django.views.generic.base import RedirectView from django.views.generic.base import RedirectView
from django.views.generic.detail import BaseDetailView from django.views.generic.detail import BaseDetailView
@ -469,9 +472,7 @@ class MapDetailMixin:
else: else:
map_statuses = AnonymousMapPermissionsForm.STATUS map_statuses = AnonymousMapPermissionsForm.STATUS
datalayer_statuses = AnonymousDataLayerPermissionsForm.STATUS datalayer_statuses = AnonymousDataLayerPermissionsForm.STATUS
properties["edit_statuses"] = [ properties["edit_statuses"] = [(i, str(label)) for i, label in map_statuses]
(i, str(label)) for i, label in map_statuses
]
properties["datalayer_edit_statuses"] = [ properties["datalayer_edit_statuses"] = [
(i, str(label)) for i, label in datalayer_statuses (i, str(label)) for i, label in datalayer_statuses
] ]
@ -1016,6 +1017,27 @@ def stats(request):
) )
@require_GET
@cache_control(max_age=60 * 60 * 24, immutable=True, public=True) # One day.
def webmanifest(request):
return simple_json_response(
**{
"icons": [
{
"src": staticfiles_storage.url("umap/favicons/icon-192.png"),
"type": "image/png",
"sizes": "192x192",
},
{
"src": staticfiles_storage.url("umap/favicons/icon-512.png"),
"type": "image/png",
"sizes": "512x512",
},
]
}
)
def logout(request): def logout(request):
do_logout(request) do_logout(request)
if is_ajax(request): if is_ajax(request):