diff --git a/.gitignore b/.gitignore index c39b2e7..4cfe060 100644 --- a/.gitignore +++ b/.gitignore @@ -64,6 +64,7 @@ coverage.xml 3.12/lib/python3.12/site-packages/ 3.12/include +3.12/bin # Tailwind CSS /static/css/dist/ diff --git a/data/db.sqlite3 b/data/db.sqlite3 index 8109e97..b64fbf2 100644 Binary files a/data/db.sqlite3 and b/data/db.sqlite3 differ diff --git a/links/templates/links/link_detail.html b/links/templates/links/link_detail.html index c338e2f..5a3ab04 100644 --- a/links/templates/links/link_detail.html +++ b/links/templates/links/link_detail.html @@ -1,103 +1,190 @@ {% extends 'base.html' %} {% load i18n %} +{% load static %} {% block content %} -
-
-
-

{% trans "Link Details" %}

- +
+
+ +
+
+
+
{% trans "Alias" %}
+
{{ link.alias }}
+
+
+
{% trans "Click Count" %}
+
{{ link.click_count }}
+
+
+
{% trans "Created At" %}
+
{{ link.created_at|date:"Y-m-d H:i" }}
+
+
+
{% trans "Updated At" %}
+
{{ link.updated_at|date:"Y-m-d H:i" }}
+
+ {% if link.link_type == 'LINK' %} +
+
{% trans "Original URL" %}
+
+ {{ link.original_url }} +
+
+ {% endif %} +
+
-
-

{{ link.alias }}

-
-
-

{% trans "Original URL" %}:

- {{ link.original_url }} -
-
-

{% trans "Total Clicks" %}:

-

{{ link.click_count }}

-
-
-

{% trans "Created At" %}:

-

{{ link.created_at|date:"Y-m-d H:i" }}

-
-
-

{% trans "Last Updated" %}:

-

{{ link.updated_at|date:"Y-m-d H:i" }}

-
-
-
-
-
-
-

{% trans "Click Statistics" %}

+ {% if link.link_type == 'CUSTOM' %} +
+
+

{% trans "Custom Content" %}

+
+
+
+ {{ rendered_text|safe }} +
+
-
- {% if click_stats != '[]' %} -
- + {% endif %} + +
+
+

{% trans "Click Statistics" %}

+
+
+
- - - {% else %} -

{% trans "No click data available yet." %}

- {% endif %}
-
{% endblock %} {% block extra_js %} + {% endblock %} + +{% block extra_css %} + +{% endblock %} diff --git a/links/views.py b/links/views.py index aa73b78..62fbb04 100644 --- a/links/views.py +++ b/links/views.py @@ -16,6 +16,7 @@ from django.http import JsonResponse, HttpResponse from django.core.serializers import serialize import random from django.utils.text import slugify +import markdown class LinkListView(ListView): model = Link @@ -161,12 +162,17 @@ class LinkDetailView(DetailView): date=TruncDate('clicked_at') ).values('date').annotate(count=Count('id')).order_by('date') - # 将查询结果转换为列表,并将日期转换为字符串 + # Convert query results to list and format dates as strings click_stats_list = list(click_stats) for item in click_stats_list: item['date'] = item['date'].strftime('%Y-%m-%d') context['click_stats'] = json.dumps(click_stats_list, cls=DjangoJSONEncoder) + + # Convert markdown to HTML if the link is a custom type + if self.object.link_type == Link.LinkType.CUSTOM: + context['rendered_text'] = markdown.markdown(self.object.text) + return context def search_aliases(request): diff --git a/new_theme/static/css/dist/styles.css b/new_theme/static/css/dist/styles.css index 085ebea..4c0c221 100644 --- a/new_theme/static/css/dist/styles.css +++ b/new_theme/static/css/dist/styles.css @@ -729,6 +729,10 @@ video { margin-left: 0.5rem; } +.mr-1 { + margin-right: 0.25rem; +} + .block { display: block; } @@ -817,6 +821,10 @@ video { max-width: 20rem; } +.max-w-none { + max-width: none; +} + .flex-grow { flex-grow: 1; } @@ -875,6 +883,15 @@ video { gap: 1rem; } +.gap-x-4 { + -moz-column-gap: 1rem; + column-gap: 1rem; +} + +.gap-y-8 { + row-gap: 2rem; +} + .space-x-3 > :not([hidden]) ~ :not([hidden]) { --tw-space-x-reverse: 0; margin-right: calc(0.75rem * var(--tw-space-x-reverse)); @@ -1087,6 +1104,16 @@ video { background-color: rgb(240 253 244 / var(--tw-bg-opacity)); } +.bg-blue-100 { + --tw-bg-opacity: 1; + background-color: rgb(219 234 254 / var(--tw-bg-opacity)); +} + +.bg-green-100 { + --tw-bg-opacity: 1; + background-color: rgb(220 252 231 / var(--tw-bg-opacity)); +} + .p-2 { padding: 0.5rem; } @@ -1139,6 +1166,16 @@ video { padding-bottom: 1.25rem; } +.px-2\.5 { + padding-left: 0.625rem; + padding-right: 0.625rem; +} + +.py-0\.5 { + padding-top: 0.125rem; + padding-bottom: 0.125rem; +} + .text-left { text-align: left; } @@ -1288,6 +1325,20 @@ video { color: rgb(21 128 61 / var(--tw-text-opacity)); } +.text-blue-800 { + --tw-text-opacity: 1; + color: rgb(30 64 175 / var(--tw-text-opacity)); +} + +.text-green-800 { + --tw-text-opacity: 1; + color: rgb(22 101 52 / var(--tw-text-opacity)); +} + +.underline { + text-decoration-line: underline; +} + .shadow { --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); @@ -1565,6 +1616,14 @@ video { } @media (min-width: 640px) { + .sm\:col-span-1 { + grid-column: span 1 / span 1; + } + + .sm\:col-span-2 { + grid-column: span 2 / span 2; + } + .sm\:inline { display: inline; } diff --git a/requirements.txt b/requirements.txt index f930391..82c78a0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,4 +9,5 @@ django-tailwind==3.8.0 fontawesome-free==5.15.3 gunicorn==22.0.0 whitenoise==5.3.0 -django-simplemde-x==1.2.0 +django-simplemde==0.1.4 +markdown==3.7