-
-
- {{ i18n.ts.ok }}
-
-
{{ i18n.ts.cancel }}
+
+
+
+
+
+
+ {{ i18n.ts._webhookSettings.name }}
+
+
+ URL
+
+
+ {{ i18n.ts._webhookSettings.secret }}
+
+
+ {{ i18n.ts._webhookSettings.events }}
+
+
+
+ {{ i18n.ts._webhookSettings._systemEvents.abuseReport }}
+
+
+ {{ i18n.ts._webhookSettings._systemEvents.abuseReportResolved }}
+
+
+ {{ i18n.ts._webhookSettings._systemEvents.userCreated }}
+
+
+
+
+
+ {{ i18n.ts.enable }}
+
+
+
+
+
+ {{ i18n.ts.ok }}
+
+ {{ i18n.ts.cancel }}
-
+
@@ -223,9 +225,12 @@ onMounted(async () => {
}
.footer {
- display: flex;
- justify-content: center;
- align-items: flex-end;
- margin-top: 20px;
+ position: sticky;
+ bottom: 0;
+ left: 0;
+ padding: 12px;
+ border-top: solid 0.5px var(--divider);
+ -webkit-backdrop-filter: var(--blur, blur(15px));
+ backdrop-filter: var(--blur, blur(15px));
}
From b44313fe3c559badc7b0bf76ba3868f945122f0b Mon Sep 17 00:00:00 2001
From: Sayamame-beans <61457993+Sayamame-beans@users.noreply.github.com>
Date: Tue, 30 Jul 2024 12:32:03 +0900
Subject: [PATCH 06/24] fix(backend): type(schema) of reactionAcceptance was
wrong (#14317)
---
packages/backend/src/models/json-schema/note.ts | 2 +-
packages/misskey-js/src/autogen/types.ts | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/packages/backend/src/models/json-schema/note.ts b/packages/backend/src/models/json-schema/note.ts
index 61f62dce60b0..432c096e484c 100644
--- a/packages/backend/src/models/json-schema/note.ts
+++ b/packages/backend/src/models/json-schema/note.ts
@@ -204,7 +204,7 @@ export const packedNoteSchema = {
reactionAcceptance: {
type: 'string',
optional: false, nullable: true,
- enum: ['likeOnly', 'likeOnlyForRemote', 'nonSensitiveOnly', 'nonSensitiveOnlyForLocalLikeOnlyForRemote'],
+ enum: ['likeOnly', 'likeOnlyForRemote', 'nonSensitiveOnly', 'nonSensitiveOnlyForLocalLikeOnlyForRemote', null],
},
reactionEmojis: {
type: 'object',
diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts
index bf35d0f4217d..52a571b6944c 100644
--- a/packages/misskey-js/src/autogen/types.ts
+++ b/packages/misskey-js/src/autogen/types.ts
@@ -4090,7 +4090,7 @@ export type components = {
}) | null;
localOnly?: boolean;
/** @enum {string|null} */
- reactionAcceptance: 'likeOnly' | 'likeOnlyForRemote' | 'nonSensitiveOnly' | 'nonSensitiveOnlyForLocalLikeOnlyForRemote';
+ reactionAcceptance: 'likeOnly' | 'likeOnlyForRemote' | 'nonSensitiveOnly' | 'nonSensitiveOnlyForLocalLikeOnlyForRemote' | null;
reactionEmojis: {
[key: string]: string;
};
From de3ddb5b4403d02b8cb7671b9cf26e87ce9a2d17 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?=
<67428053+kakkokari-gtyih@users.noreply.github.com>
Date: Tue, 30 Jul 2024 13:02:03 +0900
Subject: [PATCH 07/24] =?UTF-8?q?enhance:=20=E7=AE=A1=E7=90=86=E7=94=BB?=
=?UTF-8?q?=E9=9D=A2=E3=81=A7=E3=82=A2=E3=83=BC=E3=82=AB=E3=82=A4=E3=83=96?=
=?UTF-8?q?=E3=81=AB=E3=81=97=E3=81=9F=E3=81=8A=E7=9F=A5=E3=82=89=E3=81=9B?=
=?UTF-8?q?=E3=82=92=E8=A1=A8=E7=A4=BA=E3=83=BB=E7=B7=A8=E9=9B=86=E3=81=A7?=
=?UTF-8?q?=E3=81=8D=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=20(#14286)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* enhance: 管理画面でアーカイブにしたお知らせを表示できるように
* Update Changelog
---
CHANGELOG.md | 1 +
locales/index.d.ts | 8 +
locales/ja-JP.yml | 2 +
.../api/endpoints/admin/announcements/list.ts | 9 +-
.../frontend/src/pages/admin/_header_.vue | 5 +-
.../src/pages/admin/announcements.vue | 162 +++++++++++-------
packages/misskey-js/src/autogen/types.ts | 5 +
7 files changed, 128 insertions(+), 64 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 17c233e35800..8da94f3749f5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@
- Feat: ユーザーのアイコン/バナーの変更可否をロールで設定可能に
- 変更不可となっていても、設定済みのものを解除してデフォルト画像に戻すことは出来ます
- Feat: ユーザ作成時にSystemWebhookを送信可能に #14281
+- Enhance: 管理画面でアーカイブにしたお知らせを表示・編集できるように
- Fix: 配信停止したインスタンス一覧が見れなくなる問題を修正
- Fix: Dockerコンテナの立ち上げ時に`pnpm`のインストールで固まることがある問題
- Fix: デフォルトテーマに無効なテーマコードを入力するとUIが使用できなくなる問題を修正
diff --git a/locales/index.d.ts b/locales/index.d.ts
index 2b340ecbb595..d54b7523129d 100644
--- a/locales/index.d.ts
+++ b/locales/index.d.ts
@@ -4440,6 +4440,14 @@ export interface Locale extends ILocale {
* アーカイブ
*/
"archive": string;
+ /**
+ * アーカイブ済み
+ */
+ "archived": string;
+ /**
+ * アーカイブ解除
+ */
+ "unarchive": string;
/**
* {name}をアーカイブしますか?
*/
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index f0f849fb3831..d8531070feec 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -1106,6 +1106,8 @@ preservedUsernames: "予約ユーザー名"
preservedUsernamesDescription: "予約するユーザー名を改行で列挙します。ここで指定されたユーザー名はアカウント作成時に使えなくなりますが、管理者によるアカウント作成時はこの制限を受けません。また、既に存在するアカウントも影響を受けません。"
createNoteFromTheFile: "このファイルからノートを作成"
archive: "アーカイブ"
+archived: "アーカイブ済み"
+unarchive: "アーカイブ解除"
channelArchiveConfirmTitle: "{name}をアーカイブしますか?"
channelArchiveConfirmDescription: "アーカイブすると、チャンネル一覧や検索結果に表示されなくなり、新たな書き込みもできなくなります。"
thisChannelArchived: "このチャンネルはアーカイブされています。"
diff --git a/packages/backend/src/server/api/endpoints/admin/announcements/list.ts b/packages/backend/src/server/api/endpoints/admin/announcements/list.ts
index 87eaad31a365..7596bf44e370 100644
--- a/packages/backend/src/server/api/endpoints/admin/announcements/list.ts
+++ b/packages/backend/src/server/api/endpoints/admin/announcements/list.ts
@@ -69,6 +69,7 @@ export const paramDef = {
sinceId: { type: 'string', format: 'misskey:id' },
untilId: { type: 'string', format: 'misskey:id' },
userId: { type: 'string', format: 'misskey:id', nullable: true },
+ status: { type: 'string', enum: ['all', 'active', 'archived'], default: 'active' },
},
required: [],
} as const;
@@ -87,7 +88,13 @@ export default class extends Endpoint
{ // eslint-
) {
super(meta, paramDef, async (ps, me) => {
const query = this.queryService.makePaginationQuery(this.announcementsRepository.createQueryBuilder('announcement'), ps.sinceId, ps.untilId);
- query.andWhere('announcement.isActive = true');
+
+ if (ps.status === 'archived') {
+ query.andWhere('announcement.isActive = false');
+ } else if (ps.status === 'active') {
+ query.andWhere('announcement.isActive = true');
+ }
+
if (ps.userId) {
query.andWhere('announcement.userId = :userId', { userId: ps.userId });
} else {
diff --git a/packages/frontend/src/pages/admin/_header_.vue b/packages/frontend/src/pages/admin/_header_.vue
index c5a9609e6ed2..b88f078598ed 100644
--- a/packages/frontend/src/pages/admin/_header_.vue
+++ b/packages/frontend/src/pages/admin/_header_.vue
@@ -24,8 +24,8 @@ SPDX-License-Identifier: AGPL-3.0-only
- {{ action.text }}
-
+ {{ action.text }}
+
@@ -56,6 +56,7 @@ const props = defineProps<{
text: string;
icon: string;
asFullButton?: boolean;
+ disabled?: boolean;
handler: (ev: MouseEvent) => void;
}[];
thin?: boolean;
diff --git a/packages/frontend/src/pages/admin/announcements.vue b/packages/frontend/src/pages/admin/announcements.vue
index e7fb62ec1de8..b9e09c8d03a6 100644
--- a/packages/frontend/src/pages/admin/announcements.vue
+++ b/packages/frontend/src/pages/admin/announcements.vue
@@ -11,70 +11,83 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts._announcement.shouldNotBeUsedToPresentPermanentInfo }}
{{ i18n.ts._announcement.tooManyActiveAnnouncementDescription }}
-
- {{ announcement.title }}
-
-
-
-
-
-
- {{ announcement.text }}
-
-
-
- {{ i18n.ts.title }}
-
-
- {{ i18n.ts.text }}
-
-
- {{ i18n.ts.imageUrl }}
-
-
- {{ i18n.ts.icon }}
-
-
-
-
-
-
- {{ i18n.ts.display }}
-
-
-
-
-
{{ i18n.ts._announcement.dialogAnnouncementUxWarn }}
-
- {{ i18n.ts._announcement.forExistingUsers }}
-
-
- {{ i18n.ts._announcement.silence }}
-
-
- {{ i18n.ts._announcement.needConfirmationToRead }}
-
-
{{ i18n.tsx.nUsersRead({ n: announcement.reads }) }}
-
-
-
- {{ i18n.ts.more }}
-
+
+
+
+ {{ i18n.ts.more }}
+
+
diff --git a/packages/frontend/src/components/MkDialog.vue b/packages/frontend/src/components/MkDialog.vue
index 5c3c6aa51dd2..16cf5b1b75c6 100644
--- a/packages/frontend/src/components/MkDialog.vue
+++ b/packages/frontend/src/components/MkDialog.vue
@@ -36,7 +36,12 @@ SPDX-License-Identifier: AGPL-3.0-only
-
+
+
+
+
@@ -67,11 +72,16 @@ type Input = {
maxLength?: number;
};
+type SelectItem = {
+ value: any;
+ text: string;
+};
+
type Select = {
- items: {
- value: any;
- text: string;
- }[];
+ items: (SelectItem | {
+ sectionTitle: string;
+ items: SelectItem[];
+ })[];
default: string | null;
};
diff --git a/packages/frontend/src/os.ts b/packages/frontend/src/os.ts
index 3085f33e215f..a8dd99c85484 100644
--- a/packages/frontend/src/os.ts
+++ b/packages/frontend/src/os.ts
@@ -447,15 +447,20 @@ export function authenticateDialog(): Promise<{
});
}
+type SelectItem
= {
+ value: C;
+ text: string;
+};
+
// default が指定されていたら result は null になり得ないことを保証する overload function
export function select(props: {
title?: string;
text?: string;
default: string;
- items: {
- value: C;
- text: string;
- }[];
+ items: (SelectItem | {
+ sectionTitle: string;
+ items: SelectItem[];
+ } | undefined)[];
}): Promise<{
canceled: true; result: undefined;
} | {
@@ -465,10 +470,10 @@ export function select(props: {
title?: string;
text?: string;
default?: string | null;
- items: {
- value: C;
- text: string;
- }[];
+ items: (SelectItem | {
+ sectionTitle: string;
+ items: SelectItem[];
+ } | undefined)[];
}): Promise<{
canceled: true; result: undefined;
} | {
@@ -478,10 +483,10 @@ export function select(props: {
title?: string;
text?: string;
default?: string | null;
- items: {
- value: C;
- text: string;
- }[];
+ items: (SelectItem | {
+ sectionTitle: string;
+ items: SelectItem[];
+ } | undefined)[];
}): Promise<{
canceled: true; result: undefined;
} | {
@@ -492,7 +497,7 @@ export function select(props: {
title: props.title,
text: props.text,
select: {
- items: props.items,
+ items: props.items.filter(x => x !== undefined),
default: props.default ?? null,
},
}, {
diff --git a/packages/frontend/src/pages/my-antennas/create.vue b/packages/frontend/src/pages/my-antennas/create.vue
index 2d026d2fa976..2b8518747f2c 100644
--- a/packages/frontend/src/pages/my-antennas/create.vue
+++ b/packages/frontend/src/pages/my-antennas/create.vue
@@ -4,43 +4,33 @@ SPDX-License-Identifier: AGPL-3.0-only
-->
-
-
-
+
+
+
+
+
diff --git a/packages/frontend/src/pages/my-antennas/edit.vue b/packages/frontend/src/pages/my-antennas/edit.vue
index 9471be85750d..9f927cd1a070 100644
--- a/packages/frontend/src/pages/my-antennas/edit.vue
+++ b/packages/frontend/src/pages/my-antennas/edit.vue
@@ -4,15 +4,17 @@ SPDX-License-Identifier: AGPL-3.0-only
-->
-
-
-
+
+
+
+
+
diff --git a/packages/frontend/src/scripts/merge.ts b/packages/frontend/src/scripts/merge.ts
index 4e39a0fa06ec..9794a300da02 100644
--- a/packages/frontend/src/scripts/merge.ts
+++ b/packages/frontend/src/scripts/merge.ts
@@ -6,7 +6,7 @@
import { deepClone } from './clone.js';
import type { Cloneable } from './clone.js';
-type DeepPartial = {
+export type DeepPartial = {
[P in keyof T]?: T[P] extends Record ? DeepPartial : T[P];
};
diff --git a/packages/frontend/src/ui/deck.vue b/packages/frontend/src/ui/deck.vue
index bdb62dca15b5..af46b0641d83 100644
--- a/packages/frontend/src/ui/deck.vue
+++ b/packages/frontend/src/ui/deck.vue
@@ -24,7 +24,7 @@ SPDX-License-Identifier: AGPL-3.0-only
:ref="id"
:key="id"
:class="$style.column"
- :column="columns.find(c => c.id === id)"
+ :column="columns.find(c => c.id === id)!"
:isStacked="ids.length > 1"
@headerWheel="onWheel"
/>
@@ -95,7 +95,8 @@ SPDX-License-Identifier: AGPL-3.0-only
import { computed, defineAsyncComponent, ref, watch, shallowRef } from 'vue';
import { v4 as uuid } from 'uuid';
import XCommon from './_common_/common.vue';
-import { deckStore, addColumn as addColumnToStore, loadDeck, getProfiles, deleteProfile as deleteProfile_ } from './deck/deck-store.js';
+import { deckStore, columnTypes, addColumn as addColumnToStore, loadDeck, getProfiles, deleteProfile as deleteProfile_ } from './deck/deck-store.js';
+import type { ColumnType } from './deck/deck-store.js';
import XSidebar from '@/ui/_common_/navbar.vue';
import XDrawerMenu from '@/ui/_common_/navbar-for-mobile.vue';
import MkButton from '@/components/MkButton.vue';
@@ -152,10 +153,12 @@ window.addEventListener('resize', () => {
const snapScroll = deviceKind === 'smartphone' || deviceKind === 'tablet';
const drawerMenuShowing = ref(false);
+/*
const route = 'TODO';
watch(route, () => {
drawerMenuShowing.value = false;
});
+*/
const columns = deckStore.reactiveState.columns;
const layout = deckStore.reactiveState.layout;
@@ -174,32 +177,20 @@ function showSettings() {
const columnsEl = shallowRef();
const addColumn = async (ev) => {
- const columns = [
- 'main',
- 'widgets',
- 'notifications',
- 'tl',
- 'antenna',
- 'list',
- 'channel',
- 'mentions',
- 'direct',
- 'roleTimeline',
- ];
-
const { canceled, result: column } = await os.select({
title: i18n.ts._deck.addColumn,
- items: columns.map(column => ({
+ items: columnTypes.map(column => ({
value: column, text: i18n.ts._deck._columns[column],
})),
});
- if (canceled) return;
+ if (canceled || column == null) return;
addColumnToStore({
type: column,
id: uuid(),
name: i18n.ts._deck._columns[column],
width: 330,
+ soundSetting: { type: null, volume: 1 },
});
};
@@ -211,7 +202,7 @@ const onContextmenu = (ev) => {
};
function onWheel(ev: WheelEvent) {
- if (ev.deltaX === 0) {
+ if (ev.deltaX === 0 && columnsEl.value != null) {
columnsEl.value.scrollLeft += ev.deltaY;
}
}
@@ -242,7 +233,7 @@ function changeProfile(ev: MouseEvent) {
title: i18n.ts._deck.profile,
minLength: 1,
});
- if (canceled) return;
+ if (canceled || name == null) return;
deckStore.set('profile', name);
unisonReload();
diff --git a/packages/frontend/src/ui/deck/antenna-column.vue b/packages/frontend/src/ui/deck/antenna-column.vue
index c3dc1e4fcec3..987bd4db557e 100644
--- a/packages/frontend/src/ui/deck/antenna-column.vue
+++ b/packages/frontend/src/ui/deck/antenna-column.vue
@@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
-->
-
+
{{ column.name }}
@@ -14,7 +14,8 @@ SPDX-License-Identifier: AGPL-3.0-only
+
diff --git a/packages/frontend/src/pages/search.stories.impl.ts b/packages/frontend/src/pages/search.stories.impl.ts
new file mode 100644
index 000000000000..0110a7ab8ed1
--- /dev/null
+++ b/packages/frontend/src/pages/search.stories.impl.ts
@@ -0,0 +1,88 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and misskey-project
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+import { StoryObj } from '@storybook/vue3';
+import { HttpResponse, http } from 'msw';
+import search_ from './search.vue';
+import { userDetailed } from '@/../.storybook/fakes.js';
+import { commonHandlers } from '@/../.storybook/mocks.js';
+
+const localUser = userDetailed('someuserid', 'miskist', null, 'Local Misskey User');
+
+export const Default = {
+ render(args) {
+ return {
+ components: {
+ search_,
+ },
+ setup() {
+ return {
+ args,
+ };
+ },
+ computed: {
+ props() {
+ return {
+ ...this.args,
+ };
+ },
+ },
+ template: '',
+ };
+ },
+ args: {
+ ignoreNotesSearchAvailable: true,
+ },
+ parameters: {
+ layout: 'fullscreen',
+ msw: {
+ handlers: [
+ ...commonHandlers,
+ http.post('/api/users/show', () => {
+ return HttpResponse.json(userDetailed());
+ }),
+ http.post('/api/users/search', () => {
+ return HttpResponse.json([userDetailed(), localUser]);
+ }),
+ ],
+ },
+ },
+} satisfies StoryObj;
+
+export const NoteSearchDisabled = {
+ ...Default,
+ args: {},
+} satisfies StoryObj;
+
+export const WithUsernameLocal = {
+ ...Default,
+
+ args: {
+ ...Default.args,
+ username: localUser.username,
+ host: localUser.host,
+ },
+ parameters: {
+ layout: 'fullscreen',
+ msw: {
+ handlers: [
+ ...commonHandlers,
+ http.post('/api/users/show', () => {
+ return HttpResponse.json(localUser);
+ }),
+ http.post('/api/users/search', () => {
+ return HttpResponse.json([userDetailed(), localUser]);
+ }),
+ ],
+ },
+ },
+} satisfies StoryObj;
+
+export const WithUserType = {
+ ...Default,
+ args: {
+ type: 'user',
+ },
+} satisfies StoryObj;
diff --git a/packages/frontend/src/pages/search.user.vue b/packages/frontend/src/pages/search.user.vue
index b9c2704bc722..85d869d9cba7 100644
--- a/packages/frontend/src/pages/search.user.vue
+++ b/packages/frontend/src/pages/search.user.vue
@@ -25,7 +25,9 @@ SPDX-License-Identifier: AGPL-3.0-only