diff --git a/activities/models/emoji.py b/activities/models/emoji.py
index dce862c..61a0cd8 100644
--- a/activities/models/emoji.py
+++ b/activities/models/emoji.py
@@ -125,10 +125,12 @@ class Emoji(StatorModel):
unique_together = ("domain", "shortcode")
class urls(urlman.Urls):
- root = "/admin/emoji/"
- create = "{root}/create/"
- edit = "{root}{self.Emoji}/"
- delete = "{edit}delete/"
+ admin = "/admin/emoji/"
+ admin_create = "{admin}create/"
+ admin_edit = "{admin}{self.pk}/"
+ admin_delete = "{admin}{self.pk}/delete/"
+ admin_enable = "{admin}{self.pk}/enable/"
+ admin_disable = "{admin}{self.pk}/disable/"
emoji_regex = re.compile(r"\B:([a-zA-Z0-9(_)-]+):\B")
@@ -172,8 +174,11 @@ class Emoji(StatorModel):
self.public is None and Config.system.emoji_unreviewed_are_public
)
- def full_url(self) -> RelativeAbsoluteUrl:
- if self.is_usable:
+ def full_url_admin(self) -> RelativeAbsoluteUrl:
+ return self.full_url(always_show=True)
+
+ def full_url(self, always_show=False) -> RelativeAbsoluteUrl:
+ if self.is_usable or always_show:
if self.file:
return AutoAbsoluteUrl(self.file.url)
elif self.remote_url:
diff --git a/activities/models/hashtag.py b/activities/models/hashtag.py
index 7d34892..8430fd4 100644
--- a/activities/models/hashtag.py
+++ b/activities/models/hashtag.py
@@ -117,6 +117,8 @@ class Hashtag(StatorModel):
view = "/tags/{self.hashtag}/"
admin = "/admin/hashtags/"
admin_edit = "{admin}{self.hashtag}/"
+ admin_enable = "{admin_edit}enable/"
+ admin_disable = "{admin_edit}disable/"
timeline = "/tags/{self.hashtag}/"
hashtag_regex = re.compile(r"\B#([a-zA-Z0-9(_)]+\b)(?!;)")
diff --git a/activities/templatetags/activity_tags.py b/activities/templatetags/activity_tags.py
index 571e2d6..5280856 100644
--- a/activities/templatetags/activity_tags.py
+++ b/activities/templatetags/activity_tags.py
@@ -1,4 +1,5 @@
import datetime
+from urllib.parse import urlencode
from django import template
from django.utils import timezone
@@ -31,3 +32,18 @@ def timedeltashort(value: datetime.datetime):
years = max(days // 365.25, 1)
text = f"{years:0n}y"
return text
+
+
+@register.simple_tag(takes_context=True)
+def urlparams(context, **kwargs):
+ """
+ Generates a URL parameter string the same as the current page but with
+ the given items changed.
+ """
+ params = dict(context["request"].GET.items())
+ for name, value in kwargs.items():
+ if value:
+ params[name] = value
+ elif name in params:
+ del params[name]
+ return urlencode(params)
diff --git a/static/css/style.css b/static/css/style.css
index 8be0914..c4de68b 100644
--- a/static/css/style.css
+++ b/static/css/style.css
@@ -555,6 +555,92 @@ p.authorization-code {
color: var(--color-text-dull);
}
+/* Item tables */
+
+table.items {
+ margin: 10px 0;
+ border: 1px solid var(--color-bg-menu);
+ border-spacing: 0;
+ border-radius: 5px;
+ width: 100%;
+}
+
+table.items td {
+ padding: 10px;
+ vertical-align: middle;
+ line-height: 1.1em;
+ height: 55px;
+ position: relative;
+}
+
+table.items td small {
+ display: block;
+ color: var(--color-text-dull);
+}
+
+table.items tr:nth-of-type(2n+1) {
+ background-color: var(--color-bg-box);
+}
+
+table.items td.name {
+ width: 100%;
+}
+
+table.items td.name a.overlay,
+table.items td.icon a.overlay {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+}
+
+table.items td.icon {
+ width: 40px;
+ padding-left: 20px;
+}
+
+table.items td.icon img {
+ width: 32px;
+ display: block;
+}
+
+table.items td .bad {
+ background: var(--color-delete);
+ padding: 4px 6px;
+ border-radius: 3px;
+}
+
+table.items td.stat {
+ white-space: nowrap;
+}
+
+table.items td.actions {
+ text-align: right;
+ white-space: nowrap;
+}
+
+table.items td.actions a {
+ color: var(--color-text-dull);
+ padding: 3px 4px;
+ border-radius: 3px;
+ text-decoration: none;
+ border: 3px solid transparent;
+ margin: 0 0 0 3px;
+ cursor: pointer;
+ display: inline-block;
+ text-align: center;
+ width: 30px;
+}
+
+table.items td.actions a:hover {
+ color: var(--color-text-main);
+ background-color: rgba(255, 255, 255, 0.1);
+}
+
+table.items td.actions a.danger:hover {
+ background-color: var(--color-delete);
+}
/* Forms */
@@ -1189,13 +1275,14 @@ table.metadata td .emoji {
.view-options {
margin: 0 0 10px 0px;
+ display: flex;
}
.view-options.follows {
margin: 0 0 20px 0px;
}
-.view-options a {
+.view-options a:not(.button) {
display: inline-block;
margin: 0 10px 5px 0;
padding: 4px 12px;
@@ -1204,11 +1291,17 @@ table.metadata td .emoji {
border-radius: 3px;
}
-.view-options a:hover {
+.view-options a.button {
+ display: inline-block;
+ margin: 0 0 5px auto;
+ padding: 1px 8px;
+}
+
+.view-options a:not(.button):hover {
color: var(--color-text-dull);
}
-.view-options a.selected {
+.view-options a:not(.button).selected {
color: var(--color-text-highlight);
}
@@ -1723,7 +1816,8 @@ form .post {
z-index: 100;
}
-#image-viewer picture, #image-viewer img {
+#image-viewer picture,
+#image-viewer img {
display: block;
}
diff --git a/takahe/urls.py b/takahe/urls.py
index 76dd98f..d4e7ff5 100644
--- a/takahe/urls.py
+++ b/takahe/urls.py
@@ -148,6 +148,23 @@ urlpatterns = [
"admin/hashtags/
- If you will be serving Takahē on the domain you choose, you can leave - the "service domain" field blank. If you would like to let users create - accounts on a domain serving something else, you must pick a unique - "service domain" that pairs up to your chosen domain name, make sure - Takahē is served on that, and add redirects - for /.well-known/webfinger, /.well-known/host-meta - and /.well-known/nodeinfo from the main domain to the - service domain. + For more information about domain setup, including what service + domains are, see our documentation on domains.
{% csrf_token %} diff --git a/templates/admin/hashtags.html b/templates/admin/hashtags.html index 1e9c374..14d5d9a 100644 --- a/templates/admin/hashtags.html +++ b/templates/admin/hashtags.html @@ -3,50 +3,62 @@ {% block subtitle %}Hashtags{% endblock %} {% block content %} -