This commit is contained in:
おさむのひと 2025-02-20 18:54:30 +09:00
parent 1cb2b38dcb
commit 9b71319fb2
4 changed files with 95 additions and 0 deletions

View File

@ -0,0 +1,32 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
export class NoteMuting1739882320354 {
name = 'NoteMuting1739882320354'
async up(queryRunner) {
await queryRunner.query(`
CREATE TABLE "note_muting" (
"id" varchar(32) NOT NULL,
"userId" varchar(32) NOT NULL,
"noteId" varchar(32) NOT NULL,
"expiresAt" TIMESTAMP WITH TIME ZONE,
CONSTRAINT "PK_note_muting_id" PRIMARY KEY ("id"),
CONSTRAINT "FK_note_muting_userId" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION,
CONSTRAINT "FK_note_muting_noteId" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION
);
CREATE INDEX "IDX_note_muting_userId" ON "note_muting" ("userId");
CREATE INDEX "IDX_note_muting_noteId" ON "note_muting" ("noteId");
`);
}
async down(queryRunner) {
await queryRunner.query(`
DROP INDEX "IDX_note_muting_noteId";
DROP INDEX "IDX_note_muting_userId";
DROP TABLE "note_muting";
`);
}
}

View File

@ -7,6 +7,7 @@
import pg from 'pg'; import pg from 'pg';
import { DataSource, Logger } from 'typeorm'; import { DataSource, Logger } from 'typeorm';
import * as highlight from 'cli-highlight'; import * as highlight from 'cli-highlight';
import { MiNoteMuting } from '@/models/NoteMuting.js';
import { entities as charts } from '@/core/chart/entities.js'; import { entities as charts } from '@/core/chart/entities.js';
import { MiAbuseUserReport } from '@/models/AbuseUserReport.js'; import { MiAbuseUserReport } from '@/models/AbuseUserReport.js';
@ -196,6 +197,7 @@ export const entities = [
MiNoteReaction, MiNoteReaction,
MiNoteThreadMuting, MiNoteThreadMuting,
MiNoteUnread, MiNoteUnread,
MiNoteMuting,
MiPage, MiPage,
MiPageLike, MiPageLike,
MiGalleryPost, MiGalleryPost,

View File

@ -0,0 +1,48 @@
<!--
SPDX-FileCopyrightText: syuilo and misskey-project
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<MkPagination :pagination="blockingPagination">
<template #empty>
<div class="_fullinfo">
<img :src="infoImageUrl" class="_ghost"/>
<div>{{ i18n.ts.nothing }}</div>
</div>
</template>
<template #default="{ items }">
<div class="_gaps_s">
<div v-for="item in items" :key="item.blockee.id" :class="[$style.userItem, { [$style.userItemOpend]: expandedBlockItems.includes(item.id) }]">
<div :class="$style.userItemMain">
<MkA :class="$style.userItemMainBody" :to="userPage(item.blockee)">
<MkUserCardMini :user="item.blockee"/>
</MkA>
<button class="_button" :class="$style.userToggle" @click="toggleBlockItem(item)"><i :class="$style.chevron" class="ti ti-chevron-down"></i></button>
<button class="_button" :class="$style.remove" @click="unblock(item.blockee, $event)"><i class="ti ti-x"></i></button>
</div>
<div v-if="expandedBlockItems.includes(item.id)" :class="$style.userItemSub">
<div>Blocked at: <MkTime :time="item.createdAt" mode="detail"/></div>
<div v-if="item.expiresAt">Period: {{ new Date(item.expiresAt).toLocaleString() }}</div>
<div v-else>Period: {{ i18n.ts.indefinitely }}</div>
</div>
</div>
</div>
</template>
</MkPagination>
</template>
<script lang="ts" setup>
import MkPagination from '@/components/MkPagination.vue';
import MkUserCardMini from '@/components/MkUserCardMini.vue';
import { userPage } from '@/filters/user';
import { i18n } from '@/i18n';
import { infoImageUrl } from '@/instance';
const noteMutingPagination = {
endpoint: 'notes/muting/list' as const,
limit: 10,
};
</script>

View File

@ -172,6 +172,18 @@ SPDX-License-Identifier: AGPL-3.0-only
</MkPagination> </MkPagination>
</MkFolder> </MkFolder>
</SearchMarker> </SearchMarker>
<SearchMarker
:label="'ミュートしたノート'"
:keywords="['mute', 'note']"
>
<MkFolder>
<template #icon><i class="ti ti-ban"></i></template>
<template #label>{{ 'ミュートしたノート' }}</template>
<XNoteMute/>
</MkFolder>
</SearchMarker>
</div> </div>
</div> </div>
</SearchMarker> </SearchMarker>
@ -181,6 +193,7 @@ SPDX-License-Identifier: AGPL-3.0-only
import { ref, computed, watch } from 'vue'; import { ref, computed, watch } from 'vue';
import XInstanceMute from './mute-block.instance-mute.vue'; import XInstanceMute from './mute-block.instance-mute.vue';
import XWordMute from './mute-block.word-mute.vue'; import XWordMute from './mute-block.word-mute.vue';
import XNoteMute from './mute-block.note-mute.vue';
import MkPagination from '@/components/MkPagination.vue'; import MkPagination from '@/components/MkPagination.vue';
import { userPage } from '@/filters/user.js'; import { userPage } from '@/filters/user.js';
import { i18n } from '@/i18n.js'; import { i18n } from '@/i18n.js';