Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 2 additions & 17 deletions snowsune/context_processors.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import os

from django.conf import settings
from django.utils.safestring import mark_safe

from datetime import datetime, date
from django.utils import timezone as django_timezone

from .models import SiteSetting

Expand All @@ -28,20 +25,8 @@ def debug_mode(request):
}


# Expiry links
def expiry_links(request):
return {
"discord": mark_safe(
f"<a href=\"{os.getenv('DISCORD_URL','#')}\">Discord Server</a>"
),
}


# Quick processor for the discord invite link
# TODO: Could be made generic for all SiteSettings
def discord_invite_link(request):
invite = SiteSetting.objects.filter(key="discord_invite").first()
return {"discord_invite": invite.value if invite else ""}
def matrix_widget_link(request):
return {"matrix_widget": settings.MATRIX_WIDGET_URL}


def ko_fi_url(request):
Expand Down
5 changes: 3 additions & 2 deletions snowsune/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,7 @@
"snowsune.context_processors.version_processor",
"snowsune.context_processors.year_processor",
"snowsune.context_processors.debug_mode",
"snowsune.context_processors.expiry_links",
"snowsune.context_processors.discord_invite_link", # TODO: Make generic!
"snowsune.context_processors.matrix_widget_link",
"snowsune.context_processors.ko_fi_url",
"snowsune.context_processors.google_analytics_id",
"snowsune.context_processors.seasonal_css",
Expand Down Expand Up @@ -161,6 +160,8 @@
"DISCORD_REDIRECT_URI", f"{SITE_URL}/fops/discord/callback"
)

MATRIX_WIDGET_URL = "https://matrix.kitsunehosting.net/widget?admins=snowsune.net"

# I'll use a custom user model for user-storage
AUTH_USER_MODEL = "users.CustomUser"

Expand Down
6 changes: 3 additions & 3 deletions snowsune/templates/home.html
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
"query-input": "required name=search_term_string"
},
"sameAs": [
"{{ discord_invite }}"
"{{ matrix_widget }}"
]
}
</script>
Expand Down Expand Up @@ -87,8 +87,8 @@ <h1>Welcome to Snowsune.net!</h1>
other furry stuff!
</p>

<p><strong>You can always contact me by joining my <a href="{{ discord_invite }}" class="discord-link">Discord
community</a> or emailing me at <a href="mailto:vixi@snowsune.net">vixi@snowsune.net</a>!</strong></p>
<p><strong>You can always contact me by joining me on <a href="{% url 'matrix_redirect' %}" class="matrix-link js-matrix-widget-open">Matrix</a>
or emailing me at <a href="mailto:vixi@snowsune.net">vixi@snowsune.net</a>!</strong></p>
</header>

<!-- Latest Content Section -->
Expand Down
4 changes: 2 additions & 2 deletions snowsune/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@
from snowsune.views.randal_fanclub import RandalFanclubView
from snowsune.views.calendar import CalendarView, CalendarEventsAPIView
from snowsune.views.health import health_check
from snowsune.views.redirects import discord_redirect
from snowsune.views.redirects import matrix_redirect
from apps.thank_yous.views import thank_you_view


urlpatterns = [
# django
path("admin/", admin.site.urls),
# Redirect helpers
re_path(r"^discord(?:/.*)?$", discord_redirect, name="discord_redirect"),
re_path(r"^matrix(?:/.*)?$", matrix_redirect, name="matrix_redirect"),
# "local" urls
path("", HomeView.as_view(), name="home"),
path("projects/", ProjectsView.as_view(), name="projects"),
Expand Down
27 changes: 4 additions & 23 deletions snowsune/views/redirects.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,11 @@
import os

from django.conf import settings
from django.http import HttpRequest, HttpResponseRedirect
from django.views.decorators.http import require_http_methods

from snowsune.models import SiteSetting


@require_http_methods(["GET", "HEAD"])
def discord_redirect(_request: HttpRequest, *_args, **_kwargs):
def matrix_redirect(_request: HttpRequest, *_args, **_kwargs):
"""
Simple /discord* redirect.

Returns an HTTP 302 to discord invite url
/matrix* redirect to the Matrix join widget.
"""
target = ""

try:
value = (
SiteSetting.objects.filter(key="discord_invite")
.values_list("value", flat=True)
.first()
)
if value:
target = value.strip()
except Exception:
target = "https://snowsune.net/discord_404".strip()

return HttpResponseRedirect(target)

return HttpResponseRedirect(settings.MATRIX_WIDGET_URL)
98 changes: 64 additions & 34 deletions static/css/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -298,35 +298,71 @@ a:visited {
align-items: flex-end;
}

.discord-navbar-btn {
.matrix-navbar-btn {
display: inline-flex;
align-items: center;
gap: 0.4em;
background: #5865F2;
color: #fff;
background: var(--accent-color);
color: var(--invert-text-color);
font-weight: 600;
border-radius: var(--radius-lg);
padding: 0.35em 1em 0.35em 0.8em;
font-size: 1em;
text-decoration: none;
margin-bottom: 0em;
margin-bottom: 0;
margin-right: 0;
box-shadow: 0 2px 8px rgba(88,101,242,0.08);
box-shadow: 0 2px 8px var(--shadow-color);
transition: transform 0.12s, box-shadow 0.12s, background 0.12s;
cursor: pointer;
border: none;
font-family: inherit;
}
.login .discord-navbar-btn {
background: #5865F2;
color: #fff;
.matrix-navbar-btn:visited {
color: var(--invert-text-color);
}
.login .matrix-navbar-btn {
background: var(--accent-color);
color: var(--invert-text-color);
margin-bottom: 0.5em;
}
.login a:not(.discord-navbar-btn) {
.login a:not(.matrix-navbar-btn) {
background: #d90429;
color: #fff;
}
.login a:not(.discord-navbar-btn):hover {
.login a:not(.matrix-navbar-btn):hover {
background: #ff616f;
}

/* Matrix widget modal — bare iframe, sized to the widget card */
.matrix-widget-modal {
border: none;
border-radius: 0;
padding: 0;
width: fit-content;
max-width: calc(100vw - 2em);
height: fit-content;
max-height: calc(100vh - 2em);
background: transparent;
box-shadow: none;
overflow: visible;
}
.matrix-widget-modal::backdrop {
background: rgba(0, 0, 0, 0.35);
}
.dark-mode .matrix-widget-modal::backdrop {
background: rgba(0, 0, 0, 0.6);
}
.matrix-widget-iframe {
display: block;
width: 22rem;
max-width: calc(100vw - 2em);
/* Fits expanded widget (room + join links) without an inner scrollbar */
height: 22rem;
max-height: calc(100vh - 2em);
border: none;
background: transparent;
}

/* User Info Widget */
.user-info {
display: flex;
Expand Down Expand Up @@ -493,29 +529,21 @@ a:visited {
}
}

/* Remove old banner styles if present */
.discord-invite-banner, .discord-animated-link, .discord-icon, .discord-text {
display: none !important;
}

.discord-navbar-btn:hover {
background: #4752c4;
.matrix-navbar-btn:hover {
background: var(--accent-hover);
color: var(--invert-text-color);
transform: scale(1.06);
box-shadow: 0 4px 16px rgba(88,101,242,0.18);
box-shadow: 0 4px 16px var(--shadow-hover);
text-decoration: none;
}
.discord-navbar-icon {
.matrix-navbar-icon {
font-size: 1.2em;
margin-right: 0.2em;
animation: discord-pulse 1.2s infinite alternate;
}
@keyframes discord-bounce {
0% { transform: translateY(0); }
100% { transform: translateY(-2px); }
animation: matrix-pulse 1.2s infinite alternate;
}
@keyframes discord-pulse {
@keyframes matrix-pulse {
0% { filter: brightness(1); }
100% { filter: brightness(1.4); }
100% { filter: brightness(1.25); }
}

/* Responsive Navbar */
Expand Down Expand Up @@ -574,14 +602,16 @@ a:visited {
border-bottom: 1px solid #fff2;
margin-bottom: 0.5em;
}
/* Discord button in mobile menu */
.nav-mobile-links .discord-navbar-btn {
/* Matrix button in mobile menu */
.nav-mobile-links .matrix-navbar-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: calc(100% - 2em);
margin: 0.5em 1em;
justify-content: center;
border-bottom: 1px solid #fff2;
padding: 0.6em 1em;
box-sizing: border-box;
border-bottom: 1px solid #fff2;
}
/* User info in mobile menu */
.nav-mobile-links .user-info {
Expand Down Expand Up @@ -655,8 +685,8 @@ a:visited {
.login .user-widget {
display: none !important; /* Hide login buttons - moved to menu */
}
.login .discord-navbar-btn {
display: none !important; /* Hide discord button - moved to menu */
.login .matrix-navbar-btn {
display: none !important; /* Hide matrix button - moved to menu */
}
.login .nav-hamburger {
display: block; /* Ensure hamburger is visible */
Expand Down Expand Up @@ -874,14 +904,14 @@ a:visited {
margin-bottom: 0;
}

.discord-link {
.matrix-link {
color: var(--link-default);
text-decoration: none;
font-weight: 500;
transition: color 0.2s ease;
}

.discord-link:hover {
.matrix-link:hover {
color: var(--link-hover);
}

Expand Down
43 changes: 43 additions & 0 deletions static/js/matrix-widget.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* Embedding modal for the matrix widget!~
*/
(function () {
function init() {
const modal = document.getElementById("matrix-widget-modal");
const iframe = document.getElementById("matrix-widget-iframe");
if (!modal || !iframe) return;

const openers = document.querySelectorAll(".js-matrix-widget-open");

function openModal(event) {
if (event) event.preventDefault();
if (!iframe.getAttribute("src")) {
iframe.setAttribute("src", iframe.dataset.src);
}
modal.showModal();
}

function closeModal() {
if (modal.open) modal.close();
}

openers.forEach((el) => el.addEventListener("click", openModal));

// Close when clicking the backdrop (outside the dialog box)
modal.addEventListener("click", (event) => {
const rect = modal.getBoundingClientRect();
const inside =
event.clientX >= rect.left &&
event.clientX <= rect.right &&
event.clientY >= rect.top &&
event.clientY <= rect.bottom;
if (!inside) closeModal();
});
}

if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);
} else {
init();
}
})();
20 changes: 12 additions & 8 deletions templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,9 @@
<a href="{% url 'tools' %}">Apps/Tools</a>
<a href="{% url 'blog:blog_list' %}">Blog</a>
<a href="{% url 'comics:comic_home' %}">Webcomic</a>
{% if discord_invite %}
<a href="{{ discord_invite }}" target="_blank" rel="noopener" class="discord-navbar-btn">
<span class="discord-navbar-icon">💬</span> Join my Discord!
<a href="{% url 'matrix_redirect' %}" class="matrix-navbar-btn js-matrix-widget-open">
<span class="matrix-navbar-icon">💬</span> Join me on Matrix!
</a>
{% endif %}
{% include "users/widget.html" %}
</div>
</nav>
Expand All @@ -167,16 +165,19 @@
<div class="header-right">
<div class="login">
<button class="nav-hamburger" id="nav-hamburger" aria-label="Open navigation">&#9776;</button>
{% if discord_invite %}
<a href="{{ discord_invite }}" target="_blank" rel="noopener" class="discord-navbar-btn">
<span class="discord-navbar-icon">💬</span> Join my Discord!
<a href="{% url 'matrix_redirect' %}" class="matrix-navbar-btn js-matrix-widget-open">
<span class="matrix-navbar-icon">💬</span> Join me on Matrix!
</a>
{% endif %}
{% include "users/widget.html" %}
</div>
</div>
</header>

<dialog id="matrix-widget-modal" class="matrix-widget-modal">
<iframe id="matrix-widget-iframe" class="matrix-widget-iframe" data-src="{{ matrix_widget }}"
title="Matrix join widget" loading="lazy" scrolling="no"></iframe>
</dialog>

{% include "includes/django_messages.html" %}

<!-- Email Verification Banner -->
Expand Down Expand Up @@ -296,6 +297,9 @@ <h2>Global Links</h2>
<!-- Live Stats Script -->
<script src="{% static 'js/live-stats.js' %}"></script>

<!-- Matrix widget modal -->
<script src="{% static 'js/matrix-widget.js' %}"></script>

{% block extra_js %}{% endblock %}
</body>

Expand Down
Loading