feat: add hidden hashtags management page
This simply adds a basic admin UI to blocklist some hashtags from displaying in the trending widget. The facility existed already in the backend, but there was no UI to manipulate the list save for executing raw SQL or API calls.
This commit is contained in:
parent
ec807fc1bd
commit
cb68498fcb
4 changed files with 67 additions and 0 deletions
|
@ -201,6 +201,8 @@ clearCachedFiles: "Clear cache"
|
|||
clearCachedFilesConfirm: "Are you sure that you want to delete all cached remote files?"
|
||||
blockedInstances: "Blocked Instances"
|
||||
blockedInstancesDescription: "List the hostnames of the instances that you want to block. Listed instances will no longer be able to communicate with this instance."
|
||||
hiddenTags: "Hidden Hashtags"
|
||||
hiddenTagsDescription: "List the hashtags (without the #) of the hashtags you wish to hide from trending and explore. Hidden hashtags are still discoverable via other means."
|
||||
muteAndBlock: "Mutes and Blocks"
|
||||
mutedUsers: "Muted users"
|
||||
blockedUsers: "Blocked users"
|
||||
|
|
54
packages/client/src/pages/admin/hashtags.vue
Normal file
54
packages/client/src/pages/admin/hashtags.vue
Normal file
|
@ -0,0 +1,54 @@
|
|||
<template>
|
||||
<MkStickyContainer>
|
||||
<template #header>
|
||||
<MkPageHeader :actions="headerActions" :tabs="headerTabs" />
|
||||
</template>
|
||||
<MkSpacer :content-max="700" :margin-min="16" :margin-max="32">
|
||||
<FormSuspense :p="init">
|
||||
<FormTextarea v-model="hiddenTags" class="_formBlock">
|
||||
<span>{{ i18n.ts.hiddenTags }}</span>
|
||||
<template #caption>{{ i18n.ts.hiddenTagsDescription }}</template>
|
||||
</FormTextarea>
|
||||
|
||||
<FormButton primary class="_formBlock" @click="save"><i
|
||||
class="ph-floppy-disk-back ph-bold ph-lg"></i>
|
||||
{{ i18n.ts.save }}</FormButton>
|
||||
</FormSuspense>
|
||||
</MkSpacer>
|
||||
</MkStickyContainer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { } from 'vue';
|
||||
import FormButton from '@/components/MkButton.vue';
|
||||
import FormTextarea from '@/components/form/textarea.vue';
|
||||
import FormSuspense from '@/components/form/suspense.vue';
|
||||
import * as os from '@/os';
|
||||
import { fetchInstance } from '@/instance';
|
||||
import { i18n } from '@/i18n';
|
||||
import { definePageMetadata } from '@/scripts/page-metadata';
|
||||
|
||||
let hiddenTags: string = $ref('');
|
||||
|
||||
async function init() {
|
||||
const meta = await os.api('admin/meta');
|
||||
hiddenTags = meta.hiddenTags.join("\n");
|
||||
}
|
||||
|
||||
function save() {
|
||||
os.apiWithDialog('admin/update-meta', {
|
||||
hiddenTags: hiddenTags.split("\n").map((h: string) => h.trim()) || [],
|
||||
}).then(() => {
|
||||
fetchInstance();
|
||||
});
|
||||
}
|
||||
|
||||
const headerActions = $computed(() => []);
|
||||
|
||||
const headerTabs = $computed(() => []);
|
||||
|
||||
definePageMetadata({
|
||||
title: i18n.ts.hiddenTags,
|
||||
icon: 'ph-hash ph-bold ph-lg',
|
||||
});
|
||||
</script>
|
|
@ -181,6 +181,12 @@ const menuDef = $computed(() => [
|
|||
to: "/admin/emojis",
|
||||
active: currentPage?.route.name === "emojis",
|
||||
},
|
||||
{
|
||||
icon: "ph-hash ph-bold ph-lg",
|
||||
text: i18n.ts.hashtags,
|
||||
to: "/admin/hashtags",
|
||||
active: currentPage?.route.name === "hashtags",
|
||||
},
|
||||
{
|
||||
icon: "ph-planet ph-bold ph-lg",
|
||||
text: i18n.ts.federation,
|
||||
|
|
|
@ -450,6 +450,11 @@ export const routes = [
|
|||
name: "users",
|
||||
component: page(() => import("./pages/admin/users.vue")),
|
||||
},
|
||||
{
|
||||
path: "/hashtags",
|
||||
name: "hashtags",
|
||||
component: page(() => import("./pages/admin/hashtags.vue")),
|
||||
},
|
||||
{
|
||||
path: "/emojis",
|
||||
name: "emojis",
|
||||
|
|
Loading…
Reference in a new issue