Skip to content

Commit

Permalink
store: add dark mode (#2327)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexAubin authored May 12, 2024
1 parent ba68da3 commit 14a23a0
Show file tree
Hide file tree
Showing 11 changed files with 86 additions and 50 deletions.
3 changes: 3 additions & 0 deletions store/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ And then start the dev server:
```bash
source venv/bin/activate
FLASK_APP=app.py FLASK_ENV=development flask --debug run

# In another term, launch the tailwindcss process to autorebuild css:
cd assets; ./tailwindcss-linux-x64 --input tailwind-local.css --output tailwind.css --watch
```

## Translation
Expand Down
7 changes: 5 additions & 2 deletions store/assets/fetch_assets
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@

# Production -> download standalone tailwind to compile only what we need
wget https://github.com/tailwindlabs/tailwindcss/releases/download/v3.3.3/tailwindcss-linux-x64
wget https://github.com/tailwindlabs/tailwindcss/releases/download/v3.4.3/tailwindcss-linux-x64
chmod +x tailwindcss-linux-x64
./tailwindcss-linux-x64 --input tailwind-local.css --output tailwind.css --minify

# Development -> we use the JS magic thingy
curl -L https://cdn.tailwindcss.com?plugins=forms > tailwind-css.js
#curl -L https://cdn.tailwindcss.com?plugins=forms > tailwind-css.js

# Dark theme stuff
git clone https://github.com/jjranalli/nightwind

# Canvasjs (for the chart page only)
curl -L https://cdn.canvasjs.com/ga/canvasjs.min.js > canvasjs.min.js
Expand Down
4 changes: 2 additions & 2 deletions store/assets/tailwind-local.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
@tailwind utilities;

@layer utilities {
body {
@apply text-gray-800;
input, textarea, select {
@apply !rounded-md shadow-sm border-gray-200 !bg-neutral-50;
}
.btn {
@apply text-sm font-medium rounded-md px-4 py-2 transition;
Expand Down
5 changes: 2 additions & 3 deletions store/assets/tailwind.config.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['../templates/*.html'],
theme: {
extend: {},
},
darkMode: 'selector',
plugins: [
require('@tailwindcss/forms'),
require('./nightwind/src/index.js'),
],
safelist: [
'safelisted',
Expand Down
4 changes: 2 additions & 2 deletions store/templates/app.html
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ <h1 class="flex-0 pl-2 pt-3 {% if infos["manifest"]["name"]|length > 12 %}text-2
<span class="inline sm:hidden">{{ _("Demo") }}</span>
</a>
{% endif %}
<a aria-label="{{ _('Install with YunoHost') }}" title="{{ _('Install with YunoHost') }}" class="h-9.5 inline-block rounded-md border p-0 bg-gray-900 text-white " href="https://install-app.yunohost.org/?app={{ app_id }}">
<a aria-label="{{ _('Install with YunoHost') }}" title="{{ _('Install with YunoHost') }}" class="h-9.5 inline-block rounded-md border p-0 bg-gray-900 dark:bg-dark text-white " href="https://install-app.yunohost.org/?app={{ app_id }}">
<span class="inline-block text-[11px] leading-3 text-center py-1.5 pl-2">Install<br/>with</span>
<span class="inline-block pr-2 pt-1"><img alt="YunoHost" src="{{ url_for('static', filename='horizontal-yunohost.svg') }}"></span>
<span class="inline-block pr-2 pt-1 dark:invert"><img alt="YunoHost" src="{{ url_for('static', filename='horizontal-yunohost.svg') }}"></span>
</a>
</div>

Expand Down
51 changes: 35 additions & 16 deletions store/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="{{ url_for('static', filename='fork-awesome.min.css') }}">
{% if config.DEBUG %}
<script src="{{ url_for('static', filename='tailwind-css.js') }}"></script>
<style type="text/tailwindcss">
{{ tailwind_local }}
</style>
{% else %}
<link rel="stylesheet" href="{{ url_for('static', filename='tailwind.css') }}">
{% endif %}
<script>
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark')
} else {
document.documentElement.classList.remove('dark')
}
</script>
</head>

<body>
<body class="bg-neutral-50 text-gray-800">
<header class="pb-2 shadow-sm">
<div
class="flex h-12 items-center gap-8 pt-2 px-4 sm:px-6 lg:px-8"
Expand All @@ -36,24 +36,24 @@
<nav class="hidden md:block">
<ul class="flex items-center gap-6 text-sm">
<li>
<a class="font-bold transition hover:text-gray-500/75" href="{{ url_for('browse_catalog') }}">
<a class="font-bold transition hover:opacity-75" href="{{ url_for('browse_catalog') }}">
{{ _("Catalog") }}
</a>
</li>

<li>
<a class="font-bold transition hover:text-gray-500/75" href="{{ url_for('browse_wishlist') }}">
<a class="font-bold transition hover:opacity-75" href="{{ url_for('browse_wishlist') }}">
{{ _("Wishlist") }}
</a>
</li>
{% if packaging_enabled %}
<li>
<a class="font-bold transition hover:text-gray-500/75" href="{{ url_for('dash') }}">
<a class="font-bold transition hover:opacity-75" href="{{ url_for('dash') }}">
{{ _("Packaging dashboard") }}
</a>
</li>
<li>
<a class="font-bold transition hover:text-gray-500/75" href="{{ url_for('charts') }}">
<a class="font-bold transition hover:opacity-75" href="{{ url_for('charts') }}">
{{ _("Charts & history") }}
</a>
</li>
Expand All @@ -70,6 +70,15 @@
<i class="fa fa-external-link fa-fw" aria-hidden="true"></i>
{{ _("YunoHost documentation") }}
</a>
<a
class="inline-block"
role="button"
target="_blank"
id="toggleDarkMode"
>
<i class="fa fa-sun-o inline-block dark:hidden rounded-md border border-gray-300 px-3 py-2.5 hover:bg-gray-100" aria-hidden="true" title="{{ _('Toggle light/dark mode') }}"></i>
<i class="fa fa-moon-o hidden dark:inline-block rounded-md border border-gray-300 px-3 py-2.5 hover:bg-gray-100" aria-hidden="true" title="{{ _('Toggle light/dark mode') }}"></i>
</a>
{% if not user %}
<a
class="btn btn-primary inline-block"
Expand Down Expand Up @@ -252,14 +261,25 @@

<footer class="h-5 my-5 text-center">
<p>
{{ _("Made with <i class='text-red-500 fa fa-heart-o' aria-label='love'></i> using <a class='text-blue-800' href='https://flask.palletsprojects.com'>Flask</a> and <a class='text-blue-800' href='https://tailwindcss.com/'>TailwindCSS</a>") }}
<a class='text-blue-800' href='https://github.com/YunoHost/apps/tree/master/store'><i class='fa fa-code fa-fw' aria-hidden='true'></i> {{ _("Source") }}</a>
<a class='text-blue-800' href='https://yunohost.org/tos'>{{ _("Terms of Services") }}</a>
{{ _("Made with <i class='text-red-500 fa fa-heart-o' aria-label='love'></i> using <a class='text-blue-800 dark:text-blue-400' href='https://flask.palletsprojects.com'>Flask</a> and <a class='text-blue-800 dark:text-blue-400' href='https://tailwindcss.com/'>TailwindCSS</a>") }}
<a class='text-blue-800 dark:text-blue-400' href='https://github.com/YunoHost/apps/tree/master/store'><i class='fa fa-code fa-fw' aria-hidden='true'></i> {{ _("Source") }}</a>
<a class='text-blue-800 dark:text-blue-400' href='https://yunohost.org/tos'>{{ _("Terms of Services") }}</a>
</p>
</footer>
</body>

<script type="text/javascript">
document.getElementById('toggleDarkMode').addEventListener('click', () => {
document.documentElement.classList.toggle('dark')
if (document.documentElement.classList.contains("dark") == true)
{
localStorage.theme = 'dark';
}
else
{
localStorage.theme = 'light';
}
});
{% if user %}
document.getElementById('toggleUserMenu').addEventListener('click', () => {
document.getElementById('userMenu').classList.toggle("hidden");
Expand All @@ -269,5 +289,4 @@
document.getElementById('menu').classList.toggle("hidden");
});
</script>

</html>
18 changes: 10 additions & 8 deletions store/templates/catalog.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
>
<a
href="{{ url_for('app_info', app_id=app) }}"
class="relative block overflow-hidden rounded-lg py-2 px-4 hover:bg-gray-100 mx-2 md:mx-0"
class="relative block overflow-hidden rounded-lg py-2 px-4 hover:bg-neutral-100 mx-2 md:mx-0"
>
<div class="flex justify-between gap-4">
<div class="shrink-0">
Expand All @@ -27,7 +27,7 @@
src="{{ url_for('static', filename='app_logo_placeholder.png') }}"
{% endif %}
loading="lazy"
class="h-12 w-12 rounded-lg object-cover shadow-sm mt-1"
class="h-12 w-12 rounded-lg object-cover shadow mt-1"
>
</div>
<div class="w-full">
Expand All @@ -53,14 +53,16 @@ <h3 class="grow text-md font-bold">
</span>
</span>
</span>
<p class="max-w-[40ch] text-xs text-gray-700">
<p class="max-w-[40ch] text-xs opacity-75">
{{ infos['manifest']['description']|localize }}
</p>
<div class="hidden">
{{ infos["potential_alternative_to"]|join(', ') }}
</div>
{% if infos['category'] %}
<span class="rounded-full px-2.5 py-0.5 text-[10px] border text-{{ catalog['categories'][infos['category']]['color'] }}-600 border-{{ catalog['categories'][infos['category']]['color'] }}-400 ">
<span class="rounded-full px-2.5 py-0.5 text-[10px] border
text-{{ catalog['categories'][infos['category']]['color'] }}-600
border-{{ catalog['categories'][infos['category']]['color'] }}-400 ">
{{ catalog['categories'][infos['category']]['title']|localize|lower }}
</span>
{% endif %}
Expand Down Expand Up @@ -90,7 +92,7 @@ <h1 class="text-2xl font-bold">
id="search"
placeholder="{{ _('Search for…') }}"
{% if request.args.get("search") %}value="{{ request.args.get("search") }}"{% endif %}
class="w-full rounded-md border-gray-200 shadow-sm sm:text-sm py-2 pe-10"
class="w-full sm:text-sm py-2 pe-10"
>

<span class="absolute inset-y-0 end-0 grid w-10 place-content-center pr-4">
Expand All @@ -102,7 +104,7 @@ <h1 class="text-2xl font-bold">
<select
name="selectcategory"
id="selectcategory"
class="w-full rounded-md border-gray-200 shadow-sm sm:test-sm px-2 py-1.5"
class="w-full sm:text-sm px-2 py-1.5"
>
<option value="">{{ _("All apps") }}</option>
{% for id, category in catalog['categories'].items() %}
Expand All @@ -118,14 +120,14 @@ <h1 class="text-2xl font-bold">
<select
name="selectsort"
id="selectsort"
class="inline-block rounded-md border-gray-200 text-sm ml-1 pl-1 pr-7 h-8 py-0"
class="inline-block text-sm ml-1 pl-1 pr-7 h-8 py-0"
>
<option {% if request.args.get("sort") in [None, "popularity"] %}selected{% endif %} value="popularity">{{ _("Popularity") }}</option>
<option {% if request.args.get("sort") == "newest" %}selected{% endif %} value="newest">{{ _("Newest") }}</option>
<option {% if request.args.get("sort") == "alpha" %}selected{% endif %} value="alpha">{{ _("Alphabetical") }}</option>
</select>
</div>
<div class="inline-block flex items-center px-2 pt-2 md:pt-0 {% if not user %}text-gray-500{% endif %}" {% if not user %}title="{{ _('Requires to be logged-in') }}" aria-label="{{ _('Requires to be logged-in') }}"{% endif %}>
<div class="inline-block flex items-center px-2 pt-2 md:pt-0 {% if not user %}opacity-75{% endif %}" {% if not user %}title="{{ _('Requires to be logged-in') }}" aria-label="{{ _('Requires to be logged-in') }}"{% endif %}>
<label for="starsonly" class="inline-block relative mr-2 h-4 w-7 cursor-pointer">
<span class="sr-only">{{ _("Show only apps you starred") }}</span>
<input type="checkbox" id="starsonly" class="peer sr-only" {% if user and request.args.get("starsonly") %}checked{% endif %} {% if not user%}disabled{% endif %} >
Expand Down
10 changes: 10 additions & 0 deletions store/templates/charts.html
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ <h2 class="text-center font-medium text-xl py-4">{{ date }}</h2>
<script>
window.onload = function () {

var theme = "light1";
if (document.documentElement.classList.contains("dark") == true)
{
theme = "dark1";
}

var colors_per_level = [
"#d9534f",
"#E26D4F",
Expand All @@ -73,6 +79,8 @@ <h2 class="text-center font-medium text-xl py-4">{{ date }}</h2>
];

new CanvasJS.Chart("levelRing", {
backgroundColor: 'transparent',
theme: theme,
animationEnabled: false,
data: [{
type: "doughnut",
Expand All @@ -98,6 +106,8 @@ <h2 class="text-center font-medium text-xl py-4">{{ date }}</h2>


new CanvasJS.Chart("levelHistory", {
backgroundColor: 'transparent',
theme: theme,
animationEnabled: false,
toolTip: {
reversed: true,
Expand Down
4 changes: 2 additions & 2 deletions store/templates/dash.html
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ <h1 class="text-2xl font-bold">
<i class="fa fa-flask"></i>
{% for s in infos["testing"]["statuses"] %}
{% if s["context"] == "ci-apps-dev" %}
<i class="fa fa-{% if s["state"] == "success" %}check-circle text-green-600{% else %}times-circle text-red-600{% endif %}"></i>
<i class="fa fa-{% if s["state"] == "success" %}check-circle text-green-600{% else %}times-circle text-red-500{% endif %}"></i>
{% endif %}
{% endfor %}
{% if infos["testing"]["timestamp_updated"] | days_ago > 30 %}
Expand All @@ -158,7 +158,7 @@ <h1 class="text-2xl font-bold">
<i class="fa fa-arrow-up"></i>
{% for s in infos["ci-auto-update"]["statuses"] %}
{% if s["context"] == "ci-apps-dev" %}
<i class="fa fa-{% if s["state"] == "success" %}check-circle text-green-600{% else %}times-circle text-red-600{% endif %}"></i>
<i class="fa fa-{% if s["state"] == "success" %}check-circle text-green-600{% else %}times-circle text-red-500{% endif %}"></i>
{% endif %}
{% endfor %}
{% if infos["ci-auto-update"]["timestamp_updated"] | days_ago > 30 %}
Expand Down
8 changes: 4 additions & 4 deletions store/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
{% block main %}

<div class="mx-auto w-full text-center p-8">
<img alt="YunoHost logo" src="{{ url_for('static', filename='ynh_logo_black.svg') }}" class="w-32 mx-auto">
<img alt="YunoHost logo" src="{{ url_for('static', filename='ynh_logo_black.svg') }}" class="w-32 mx-auto dark:invert">
<h1 class="text-2xl font-bold">
{{ _("Application Store") }}
</h1>
</div>

<div class="grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 max-w-screen-lg mx-auto pt-5">
<div class="text-center border rounded-lg h-32 mx-3 sm:mx-0">
<div class="text-center border rounded-lg h-32 mx-3 sm:mx-0 border-gray-200">
<a
href="{{ url_for('browse_catalog') }}"
class="h-full relative block overflow-hidden hover:bg-gray-200 pt-12"
Expand All @@ -23,7 +23,7 @@ <h2 class="text-md font-bold">
</a>
</div>
{% for id, category in catalog['categories'].items() %}
<div class="text-center border rounded-lg h-32 mx-3 sm:mx-0">
<div class="text-center border rounded-lg h-32 mx-3 sm:mx-0 border-gray-200">
<a
href="{{ url_for('browse_catalog', category=id) }}"
class="h-full relative block overflow-hidden hover:bg-gray-200 pt-10"
Expand All @@ -32,7 +32,7 @@ <h2 class="text-md font-bold">
<i class="fa fa-{{ category['icon'] }}" aria-hidden="true"></i>
{{ category['title']|localize }}
</h2>
<p class="mx-auto max-w-[40ch] text-xs text-gray-500">
<p class="mx-auto max-w-[40ch] text-xs opacity-75">
{{ category['description']|localize }}
</p>
</a>
Expand Down
Loading

0 comments on commit 14a23a0

Please sign in to comment.