diff --git a/locales/en-US.yml b/locales/en-US.yml
index 2f855ef9eb..7e24a62022 100644
--- a/locales/en-US.yml
+++ b/locales/en-US.yml
@@ -265,6 +265,9 @@ noCustomEmojis: "There are no emoji"
noJobs: "There are no jobs"
federating: "Federating"
blocked: "Blocked"
+blockedByBase: "This host is blocked implicitly because a base domain is blocked. To unblock this host, first unblock the base domain(s)."
+silencedByBase: "This host is silenced implicitly because a base domain is silenced. To un-silence this host, first un-silence the base domain(s)."
+mediaSilencedByBase: "This host's media is silenced implicitly because a base domain's media is silenced. To un-silence this host, first un-silence the base domain(s)."
suspended: "Suspended"
all: "All"
subscribing: "Subscribing"
diff --git a/locales/index.d.ts b/locales/index.d.ts
index 8a17705600..9a02dbc1e2 100644
--- a/locales/index.d.ts
+++ b/locales/index.d.ts
@@ -1076,6 +1076,18 @@ export interface Locale extends ILocale {
* ブロック中
*/
"blocked": string;
+ /**
+ * This host is blocked implicitly because a base domain is blocked. To unblock this host, first unblock the base domain(s).
+ */
+ "blockedByBase": string;
+ /**
+ * This host is silenced implicitly because a base domain is silenced. To un-silence this host, first un-silence the base domain(s).
+ */
+ "silencedByBase": string;
+ /**
+ * This host's media is silenced implicitly because a base domain's media is silenced. To un-silence this host, first un-silence the base domain(s).
+ */
+ "mediaSilencedByBase": string;
/**
* 配信停止
*/
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index 724e9a23a1..c422172eb9 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -265,6 +265,9 @@ noCustomEmojis: "絵文字はありません"
noJobs: "ジョブはありません"
federating: "連合中"
blocked: "ブロック中"
+blockedByBase: "This host is blocked implicitly because a base domain is blocked. To unblock this host, first unblock the base domain(s)."
+silencedByBase: "This host is silenced implicitly because a base domain is silenced. To un-silence this host, first un-silence the base domain(s)."
+mediaSilencedByBase: "This host's media is silenced implicitly because a base domain's media is silenced. To un-silence this host, first un-silence the base domain(s)."
suspended: "配信停止"
all: "全て"
subscribing: "購読中"
diff --git a/packages/backend/src/server/api/endpoints/admin/meta.ts b/packages/backend/src/server/api/endpoints/admin/meta.ts
index 5a69fbf679..dbfa31024a 100644
--- a/packages/backend/src/server/api/endpoints/admin/meta.ts
+++ b/packages/backend/src/server/api/endpoints/admin/meta.ts
@@ -128,7 +128,7 @@ export const meta = {
},
silencedHosts: {
type: 'array',
- optional: true,
+ optional: false,
nullable: false,
items: {
type: 'string',
diff --git a/packages/frontend/src/pages/instance-info.vue b/packages/frontend/src/pages/instance-info.vue
index 4ff26197d8..821cd599eb 100644
--- a/packages/frontend/src/pages/instance-info.vue
+++ b/packages/frontend/src/pages/instance-info.vue
@@ -45,10 +45,13 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts._delivery.stop }}
{{ i18n.ts._delivery.resume }}
- {{ i18n.ts.blockThisInstance }}
- {{ i18n.ts.silenceThisInstance }}
+ {{ i18n.ts.blockedByBase }}
+ {{ i18n.ts.blockThisInstance }}
+ {{ i18n.ts.silencedByBase }}
+ {{ i18n.ts.silenceThisInstance }}
Mark as NSFW
- {{ i18n.ts.mediaSilenceThisInstance }}
+ {{ i18n.ts.mediaSilencedByBase }}
+ {{ i18n.ts.mediaSilenceThisInstance }}
Refresh metadata
{{ i18n.ts.moderationNote }}
@@ -156,6 +159,7 @@ import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue';
import { getProxiedImageUrlNullable } from '@/scripts/media-proxy.js';
import { dateString } from '@/filters/date.js';
import MkTextarea from '@/components/MkTextarea.vue';
+import MkInfo from '@/components/MkInfo.vue';
const props = defineProps<{
host: string;
@@ -174,6 +178,21 @@ const isMediaSilenced = ref(false);
const faviconUrl = ref(null);
const moderationNote = ref('');
+const baseDomains = computed(() => {
+ const domains: string[] = [];
+
+ const parts = props.host.toLowerCase().split('.');
+ for (let s = 1; s < parts.length; s++) {
+ const domain = parts.slice(s).join('.');
+ domains.push(domain);
+ }
+
+ return domains;
+});
+const isBaseBlocked = computed(() => meta.value && baseDomains.value.some(d => meta.value?.blockedHosts.includes(d)));
+const isBaseSilenced = computed(() => meta.value && baseDomains.value.some(d => meta.value?.silencedHosts.includes(d)));
+const isBaseMediaSilenced = computed(() => meta.value && baseDomains.value.some(d => meta.value?.mediaSilencedHosts.includes(d)));
+
const usersPagination = {
endpoint: iAmModerator ? 'admin/show-users' : 'users' as const,
limit: 10,
diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts
index 0e83bdfcca..e3bf828982 100644
--- a/packages/misskey-js/src/autogen/types.ts
+++ b/packages/misskey-js/src/autogen/types.ts
@@ -5199,7 +5199,7 @@ export type operations = {
enableEmail: boolean;
enableServiceWorker: boolean;
translatorAvailable: boolean;
- silencedHosts?: string[];
+ silencedHosts: string[];
mediaSilencedHosts: string[];
pinnedUsers: string[];
hiddenTags: string[];