diff --git a/Spybot2/settings.py b/Spybot2/settings.py index 088caab..f30db77 100644 --- a/Spybot2/settings.py +++ b/Spybot2/settings.py @@ -75,16 +75,6 @@ 'django_bootstrap5', ] -MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', -] - ROOT_URLCONF = 'Spybot2.urls' TEMPLATES = [ @@ -159,6 +149,8 @@ 'spybot.auth.backend.link_backend.LinkAuthBackend', ] +LOGIN_URL = '/login' + # Passkeys FIDO_SERVER_NAME = "Spybot local" #KEY_ATTACHMENT = passkeys.Attachment.CROSS_PLATFORM diff --git a/frontend/chart_utils.js b/frontend/chart_utils.js new file mode 100644 index 0000000..32b0c90 --- /dev/null +++ b/frontend/chart_utils.js @@ -0,0 +1,23 @@ +export const onChartRenderTrigger = (now, call) => { + const observer = new MutationObserver(function (mutations) { + mutations.forEach(function (mutation) { + if (mutation.type === "attributes" && mutation.attributeName === 'data-bs-theme') { + call() + } + }); + }); + observer.observe(document.body, { + attributes: true //configure it to listen to attribute changes + }); + + if (now === true) call(); +} + +export const onChartReady = (call) => { + document.addEventListener("DOMContentLoaded", call) +}; + +export const isDarkMode = () => { + return document.body.classList.contains("theme-dark"); +} + diff --git a/frontend/early.js b/frontend/early.js new file mode 100644 index 0000000..8edb55b --- /dev/null +++ b/frontend/early.js @@ -0,0 +1,5 @@ +// anything that needs to be loaded immediately upon page load goes here + +import * as chart_utils from './chart_utils' + +Object.assign(window, chart_utils) \ No newline at end of file diff --git a/frontend/rollup.config.mjs b/frontend/rollup.config.mjs index 0237931..9ef024e 100644 --- a/frontend/rollup.config.mjs +++ b/frontend/rollup.config.mjs @@ -1,7 +1,7 @@ import { nodeResolve } from '@rollup/plugin-node-resolve'; import css from "rollup-plugin-import-css"; -export default { +export default [{ context: 'window', input: 'main.js', output: { @@ -10,4 +10,14 @@ export default { name: 'jsbundle', }, plugins: [nodeResolve(), css({'output': 'main.css'})] -}; \ No newline at end of file +}, +{ + context: 'window', + input: 'early.js', + output: { + dir: 'output', + format: 'iife', + name: 'jsbundle', + }, + plugins: [nodeResolve()] +}]; \ No newline at end of file diff --git a/spybot/static/theme.js b/spybot/static/theme.js index f837e7a..865b8d3 100644 --- a/spybot/static/theme.js +++ b/spybot/static/theme.js @@ -31,7 +31,9 @@ function configureTheme(wantedTheme) { document.body.classList.remove('theme-dark', 'theme-light'); document.body.classList.add(`theme-${realTheme}`); if (realTheme === 'dark') { - document.body.setAttribute("data-bs-theme", realTheme) + if (document.body.getAttribute('data-bs-theme') !== realTheme) { + document.body.setAttribute("data-bs-theme", realTheme) + } } else { document.body.removeAttribute("data-bs-theme") } @@ -51,6 +53,6 @@ function configureTheme(wantedTheme) { applyTheme(theme); } -window.matchMedia("(prefers-color-scheme: dark)").onchange = configureTheme +window.matchMedia("(prefers-color-scheme: dark)").addEventListener('change', configureTheme) // configure theme now configureTheme() \ No newline at end of file diff --git a/spybot/templates/spybot/base/base.html b/spybot/templates/spybot/base/base.html index f85b05a..131bccc 100644 --- a/spybot/templates/spybot/base/base.html +++ b/spybot/templates/spybot/base/base.html @@ -12,6 +12,7 @@ + {% block header %} {% endblock %} diff --git a/spybot/templates/spybot/home/activity_fragment.html b/spybot/templates/spybot/home/activity_fragment.html index 83aee33..634bdf2 100644 --- a/spybot/templates/spybot/home/activity_fragment.html +++ b/spybot/templates/spybot/home/activity_fragment.html @@ -114,12 +114,9 @@

Recent activity

})).render(); } - console.log("checking document loading state") if (document.readyState === "loading") { - console.log("loading"); document.addEventListener("DOMContentLoaded", renderActivityChart); } else { - console.log("already loaded"); renderActivityChart(); } diff --git a/spybot/templates/spybot/home/channel_tree_map.html b/spybot/templates/spybot/home/channel_tree_map.html index 061327f..84860c4 100644 --- a/spybot/templates/spybot/home/channel_tree_map.html +++ b/spybot/templates/spybot/home/channel_tree_map.html @@ -11,67 +11,78 @@

Channel popularity

function getCSSVar(name) { return getComputedStyle(document.body).getPropertyValue(name) } -document.addEventListener("DOMContentLoaded", function () { - if (!window.ApexCharts) return +onChartReady(() => { const raw_data = JSON.parse(document.querySelector('#channel-data').textContent) - new ApexCharts(document.querySelector("#chart-channel-tree-map"), { - chart: { - type: 'treemap', - toolbar: { - show: false, + + const chartOptions = () => { + return { + chart: { + type: 'treemap', + toolbar: { + show: false, + }, + zoom: {enabled: false}, + height: '100%', + parentHeightOffset: 0, + }, + series: [ + { + name: 'Talking', + data: raw_data.filter(o => o.name !== "AFK" && o.name !== "bei Bedarf anstupsen") + .map(o => { return {x: o.name, y: o.percentage}}) + }, + { + name: 'Inactive', + data: raw_data.filter(o => o.name === "AFK" || o.name === "bei Bedarf anstupsen") + .map(o => { return {x: o.name, y: o.percentage}}) + } + ], + plotOptions: { + treemap: { + enableShades: true, + shadeIntensity: 0.3, + } }, - zoom: {enabled: false}, - height: '100%', - parentHeightOffset: 0, - }, - series: [ - { - name: 'Talking', - data: raw_data.filter(o => o.name !== "AFK" && o.name !== "bei Bedarf anstupsen") - .map(o => { return {x: o.name, y: o.percentage}}) + stroke:{ + width: 5, + colors: [getCSSVar('--tblr-bg-surface')], }, - { - name: 'Inactive', - data: raw_data.filter(o => o.name === "AFK" || o.name === "bei Bedarf anstupsen") - .map(o => { return {x: o.name, y: o.percentage}}) - } - ], - plotOptions: { - treemap: { - enableShades: true, - shadeIntensity: 0.3, - } - }, - stroke:{ - width: 5, - colors: [getCSSVar('--tblr-bg-surface')], - }, - colors: [tabler.getColor("primary"), tabler.getColor("red")], - dataLabels: { - enabled: true, - offsetY: -5, - formatter: function(text, op) { - return [text, op.value.toFixed(1) + "%"] + colors: [tabler.getColor("primary"), tabler.getColor("red")], + dataLabels: { + enabled: true, + offsetY: -5, + formatter: function(text, op) { + return [text, op.value.toFixed(1) + "%"] + }, }, - }, - grid: { - padding: { - top: -20, - right: 0, - left: 0, - bottom: 0 + grid: { + padding: { + top: -20, + right: 0, + left: 0, + bottom: 0 + }, }, - }, - tooltip:{ - theme: 'dark', - marker: {show: false}, - y: { - formatter: y => { return y.toFixed(1) + "%" }, + tooltip:{ + theme: 'dark', + marker: {show: false}, + y: { + formatter: y => { return y.toFixed(1) + "%" }, + }, + }, + legend: { + show: false, }, - }, - legend: { - show: false, - }, - }).render() + }; + } + let chart = null; + + onChartRenderTrigger(true, () => { + if (chart !== null) { + chart.destroy(); + } + chart = new ApexCharts(document.querySelector("#chart-channel-tree-map"), chartOptions()) + chart.render(); + }); }); \ No newline at end of file diff --git a/spybot/templates/spybot/home/tod_histogram.html b/spybot/templates/spybot/home/tod_histogram.html index 3a63c36..3f7940d 100644 --- a/spybot/templates/spybot/home/tod_histogram.html +++ b/spybot/templates/spybot/home/tod_histogram.html @@ -72,8 +72,8 @@

Time of day histogram

type: "numeric", min: 0, max: 24, - tickAmount: 12, - labels: {formatter: x => x /*Math.round(x)*/}, + tickAmount: 11, + labels: {formatter: x => `${x <= 12 ? x : x-12}${x < 12 ? 'am' : 'pm'}`}, title: { text: "Hours", offsetY: 68, diff --git a/spybot/templates/spybot/timeline.html b/spybot/templates/spybot/timeline.html index 3a58df2..20e450b 100644 --- a/spybot/templates/spybot/timeline.html +++ b/spybot/templates/spybot/timeline.html @@ -84,7 +84,7 @@ x: { format: 'HH:mm:ss' }, - theme: document.body.classList.contains("theme-dark") ? 'dark' : 'light' + theme: isDarkMode() ? 'dark' : 'light' }, theme: { palette: 'palette2' diff --git a/spybot/templates/spybot/user.html b/spybot/templates/spybot/user.html index 943d840..b0f16b7 100644 --- a/spybot/templates/spybot/user.html +++ b/spybot/templates/spybot/user.html @@ -3,11 +3,32 @@ {% load util %} {% block content %} -
+
+ {{ user.user_name|make_list|first }} + {{ user.user_name }} +
+
-

{{ user.user_name }}

+

Awards

+
+
+
+ Award of the week Medals +
+
+ {{ user.gold }} x {% tabler_icon 'medal' class="medal gold" %} + {{ user.silver }} x {% tabler_icon 'medal' class="medal silver" %} + {{ user.bronze }} x {% tabler_icon 'medal' class="medal bronze" %} +
+
+
+
+
+
+
+

Statistics

@@ -26,17 +47,6 @@

{{ user.user_name }}

-
-
- Medals -
-
- {% tabler_icon 'medal' class="medal gold" %}{{ user.gold }} - {% tabler_icon 'medal' class="medal silver" %}{{ user.silver }} - {% tabler_icon 'medal' class="medal bronze" %}{{ user.bronze }} -
-
- {% if not user.online %}
@@ -105,7 +115,7 @@

{{ user.user_name }}

{% if u.names|length > 0 %} - Not Former Names known + No former names known {% endif %}
    @@ -140,57 +150,164 @@

    {{ user.user_name }}

+
+
+
+

Monthly activity chart

+
+
+
+
+
+
+ {{ months|json_script:"months_data" }} +